			<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
  	<title>bingoJS_V1.3.0</title>
  	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	<style>
		        body {
            color: #666666;
            font-family: 微软雅黑,Verdana,sans-serif,宋体;
            font-size: 14px;
            margin: 0;
            padding: 0;
        }
        a {
            color: #999999;
            text-decoration: none;
        }
        a:hover {
            color: #16B28F;
        }
        .sin_navi ul {
            list-style: none outside none;
            margin: 0;
            padding: 0 0 0 10px;
        }
        .sin_navi ul li {
            line-height: 30px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        li {
            line-height: 24px;
        }
        table {
            border-left: 1px solid #CCCCCC;
            border-top: 1px solid #CCCCCC;
            margin: 5px 10px;
            text-align: left;
            width: 678px;
        }
        table th {
            background-color: #EEEEEE;
            border-bottom: 1px solid #CCCCCC;
            border-right: 1px solid #CCCCCC;
            padding: 10px;
        }
        table td {
            border-bottom: 1px solid #CCCCCC;
            border-right: 1px solid #CCCCCC;
        }
        p {
            line-height: 24px;
            margin: 10px;
        }
        h1, h2, h3, h4, h5, h6 {
            color: #111111;
            font-weight: normal;
            margin: 0;
            padding: 0;
        }
        h1 {
            font-size: 26px;
        }
        h2 {
            border-bottom: 1px dashed #CCCCCC;
            font-size: 24px;
            padding: 10px 0;
        }
        h3 {
            font-size: 20px;
            padding: 8px 0;
        }
        h4 {
            font-size: 18px;
            margin-left: 10px;
            padding: 5px 0;
        }
        h5 {
            font-size: 16px;
            margin-left: 10px;
            padding: 5px 0;
        }
        h6 {
            font-size: 16px;
            margin-left: 10px;
            padding: 5px 0;
        }
        blockquote {
            background: url("../../../img/blockquote.gif") no-repeat scroll left top #F4F5F7;
            margin: 5px 10px;
            padding: 10px 10px 10px 30px;
        }
        pre {
            background: none repeat scroll 0 0 #EEEEEE;
            margin: 5px 10px;
            padding: 10px;
        }
        .sin_callout {
            margin: 5px 10px;
        }
        .sin_header {
            background-color: #F7F7F7;
            border-bottom: 1px solid #CCCCCC;
            height: 80px;
            width: 100%;
        }
        .sin_title {
            margin: 0 auto;
            width: 1000px;
        }
        .sin_title_text {
            color: #000000;
            float: left;
            line-height: 80px;
        }
        .sin_version {
            color: #999999;
            float: left;
            font-size: 14px;
            padding-top: 25px;
            margin-left: 10px;
        }
        .sin_main {
            margin: 0 auto;
            width: 1000px;
        }
        .sin_navi {
            float: left;
            margin-bottom: 20px;
            overflow-y: scroll;
            padding: 0;
            position: relative;
            width: 279px;
            z-index: 1;
        }
        .sin_navi_nomove {
            position: fixed;
            top: 0;
        }
        .sin_navi_ca a {
            color: #333333;
        }
        .sin_navi_ca a:hover {
            color: #16B28F;
        }
        .sin_navi_current {
            border-right: 3px solid #16B28F;
        }
        .sin_navi_current a {
            color: #16B28F;
        }
        .sin_content {
            background-color: #FFFFFF;
            border-left: 1px solid #CCCCCC;
            float: left;
            margin-left: -20px;
            padding: 10px 20px;
            position: relative;
            width: 699px;
            z-index: 2;
        }
        .sin_content_mar {
            margin-left: 259px;
        }
        .sin_footer {
            border-top: 1px solid #CCCCCC;
            color: #999999;
            height: 80px;
            line-height: 80px;
            margin: 0 auto;
            text-align: center;
        }
        .sin_info {
            background: none repeat scroll 0 0 #FFFFCC;
            border: 1px solid #D5D4D4;
            border-radius: 4px 4px 4px 4px;
            color: #999999;
            margin: 10px 0;
            padding: 14px;
        }
        .sin_link_logo {
            color: #16B28F;
            font-size: 12px;
            margin-left: 10px;
        }
        .sin_text {
            margin-bottom: 10px;
        }
        .d_callout {
            margin-bottom: 10px;
        }
        .d_callout_info {
            background: none repeat scroll 0 0 #F4F8FA;
            border-left: 4px solid #5BC0DE;
            padding: 10px;
        }
        .d_callout_warn {
            background: none repeat scroll 0 0 #FCF8F2;
            border-left: 4px solid #F0AD4E;
            padding: 10px;
        }
        .d_callout_danger {
            background: none repeat scroll 0 0 #FDF7F7;
            border-left: 4px solid #D9534F;
            padding: 10px;
        }
        .d_callout_success {
            background: none repeat scroll 0 0 #F3F8F3;
            border-left: 4px solid #50AF51;
            padding: 10px;
        }
        .d_callout input {
            background-color: rgba(0, 0, 0, 0);
            font-size: 15px;
            margin-bottom: 5px;
            padding: 10px 5px 0 10px;
        }
        .d_callout textarea {
            background-color: rgba(0, 0, 0, 0);
        }
        .d_callout_icons a {
            color: #AAAAAA;
            margin-left: 10px;
        }
        a.d_callout_icon_info {
            color: #5BC0DE;
        }
        a.d_callout_icon_warn {
            color: #F0AD4E;
        }
        a.d_callout_icon_danger {
            color: #D9534F;
        }
        a.d_callout_icon_success {
            color: #50AF51;
        }
        .clear {
            clear: both;
        }

	</style>
</head>
<body>
	<div class="sin_header">
		<div class="sin_title">
			<h1 class="sin_title_text">bingoJS</h1>
			<span class="sin_version">V1.3.0</span>
			<div class="clear"></div>
		</div>
		<div id="top_end"></div>
	</div>
	<div class="sin_main">
		<div class="sin_navi" id="sin_navi_id">
			<ul style="margin: 20px 0;">
				    																																													<li style="width: 246px;" id="navi_text_55576">
									<a href="#text_55576">
										概述
									</a>	
								</li>
																															<li class="sin_navi_ca" style="width: 246px;" id="navi_category_13121">
								<a href="#category_13121">
									启动
								</a>
							</li>
										<ul>
																			<li style="width:236px" id="navi_text_55579">
						<a href="#text_55579">
							hello world
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55580">
						<a href="#text_55580">
							action&amp;view
						</a>	
					</li>
											</ul>
																									<li class="sin_navi_ca" style="width: 246px;" id="navi_category_13127">
								<a href="#category_13127">
									数据绑定
								</a>
							</li>
										<ul>
																			<li style="width:236px" id="navi_text_55655">
						<a href="#text_55655">
							绑定与同步
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55656">
						<a href="#text_55656">
							观察者(observer)
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55657">
						<a href="#text_55657">
							variable变量
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55658">
						<a href="#text_55658">
							model
						</a>	
					</li>
											</ul>
																									<li class="sin_navi_ca" style="width: 246px;" id="navi_category_13130">
								<a href="#category_13130">
									MVC开发模式
								</a>
							</li>
										<ul>
																			<li style="width:236px" id="navi_text_55662">
						<a href="#text_55662">
							基础组成元素
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55663">
						<a href="#text_55663">
							route（路由）
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55664">
						<a href="#text_55664">
							按需加载开发
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55665">
						<a href="#text_55665">
							使用其他框架或库
						</a>	
					</li>
											</ul>
																																									<li style="width: 246px;" id="navi_text_55577">
									<a href="#text_55577">
										多版本共存
									</a>	
								</li>
																																															<li style="width: 246px;" id="navi_text_55578">
									<a href="#text_55578">
										demo
									</a>	
								</li>
																															<li class="sin_navi_ca" style="width: 246px;" id="navi_category_13135">
								<a href="#category_13135">
									开发参考
								</a>
							</li>
										<ul>
																			<li style="width:236px" id="navi_text_55696">
						<a href="#text_55696">
							概述
						</a>	
					</li>
																										<li style="width:236px" id="navi_text_55697">
						<a href="#text_55697">
							定义模块
						</a>	
					</li>
																<li class="sin_navi_ca" style="width:236px" id="navi_category_13128">
					<a href="#category_13128">
						服务service
					</a>
				</li>
							<ul>
																			<li style="width:226px" id="navi_text_55659">
						<a href="#text_55659">
							概述
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55660">
						<a href="#text_55660">
							定义与使用
						</a>	
					</li>
											</ul>
													<li class="sin_navi_ca" style="width:236px" id="navi_category_13131">
					<a href="#category_13131">
						模板指令command
					</a>
				</li>
							<ul>
									<li class="sin_navi_ca" style="width:226px" id="navi_category_13124">
					<a href="#category_13124">
						模板指令
					</a>
				</li>
							<ul>
																			<li style="width:216px" id="navi_text_55589">
						<a href="#text_55589">
							概述
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55590">
						<a href="#text_55590">
							bg-action
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55591">
						<a href="#text_55591">
							bg-action-add
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55592">
						<a href="#text_55592">
							bg-route
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55593">
						<a href="#text_55593">
							bg-route-loaded
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55594">
						<a href="#text_55594">
							bg-render / bg-for
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55595">
						<a href="#text_55595">
							bg-include
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55596">
						<a href="#text_55596">
							bg-render-include
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55597">
						<a href="#text_55597">
							bg-if
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55598">
						<a href="#text_55598">
							bg-render-if
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55599">
						<a href="#text_55599">
							bg-attr
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55600">
						<a href="#text_55600">
							bg-style
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55601">
						<a href="#text_55601">
							bg-model
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55602">
						<a href="#text_55602">
							bg-text
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55603">
						<a href="#text_55603">
							bg-html
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55604">
						<a href="#text_55604">
							bg-not-compile
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55605">
						<a href="#text_55605">
							事件指令（event）
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55606">
						<a href="#text_55606">
							其它常用指令
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55703">
						<a href="#text_55703">
							bg-loaded
						</a>	
					</li>
											</ul>
													<li class="sin_navi_ca" style="width:226px" id="navi_category_13125">
					<a href="#category_13125">
						自定义模板指令
					</a>
				</li>
							<ul>
																			<li style="width:216px" id="navi_text_55607">
						<a href="#text_55607">
							指令名称定义
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55608">
						<a href="#text_55608">
							指令的执行过程
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55609">
						<a href="#text_55609">
							简单的自定义
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55610">
						<a href="#text_55610">
							完整的自定义
						</a>	
					</li>
											</ul>
																							<li style="width:226px" id="navi_text_55666">
						<a href="#text_55666">
							数据绑定与模板
						</a>	
					</li>
											</ul>
													<li class="sin_navi_ca" style="width:236px" id="navi_category_13133">
					<a href="#category_13133">
						过滤器filter
					</a>
				</li>
							<ul>
																			<li style="width:226px" id="navi_text_55692">
						<a href="#text_55692">
							概述
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55693">
						<a href="#text_55693">
							自带filter
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55694">
						<a href="#text_55694">
							自定义filter
						</a>	
					</li>
											</ul>
													<li class="sin_navi_ca" style="width:236px" id="navi_category_13134">
					<a href="#category_13134">
						模板render
					</a>
				</li>
							<ul>
																			<li style="width:226px" id="navi_text_55695">
						<a href="#text_55695">
							概述
						</a>	
					</li>
																<li class="sin_navi_ca" style="width:226px" id="navi_category_13123">
					<a href="#category_13123">
						render语法
					</a>
				</li>
							<ul>
																			<li style="width:216px" id="navi_text_55582">
						<a href="#text_55582">
							输出语句
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55583">
						<a href="#text_55583">
							if
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55584">
						<a href="#text_55584">
							for
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55585">
						<a href="#text_55585">
							for /
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55586">
						<a href="#text_55586">
							tmpl
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55587">
						<a href="#text_55587">
							循环外部
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55588">
						<a href="#text_55588">
							内置变量
						</a>	
					</li>
											</ul>
								</ul>
													<li class="sin_navi_ca" style="width:236px" id="navi_category_13136">
					<a href="#category_13136">
						注入inject
					</a>
				</li>
							<ul>
																			<li style="width:226px" id="navi_text_55698">
						<a href="#text_55698">
							什么是注入
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55699">
						<a href="#text_55699">
							定义factory
						</a>	
					</li>
																<li class="sin_navi_ca" style="width:226px" id="navi_category_13132">
					<a href="#category_13132">
						框架自带注入
					</a>
				</li>
							<ul>
																			<li style="width:216px" id="navi_text_55667">
						<a href="#text_55667">
							$veiw
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55668">
						<a href="#text_55668">
							$viewnode
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55669">
						<a href="#text_55669">
							$attr
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55670">
						<a href="#text_55670">
							$node
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55671">
						<a href="#text_55671">
							node
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55672">
						<a href="#text_55672">
							$rootView
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55673">
						<a href="#text_55673">
							$compile
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55674">
						<a href="#text_55674">
							$bindContext
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55675">
						<a href="#text_55675">
							$nodeContext
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55676">
						<a href="#text_55676">
							$ajax
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55677">
						<a href="#text_55677">
							$tmpl
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55678">
						<a href="#text_55678">
							$factory
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55679">
						<a href="#text_55679">
							$var
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55680">
						<a href="#text_55680">
							$model
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55681">
						<a href="#text_55681">
							$observer
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55682">
						<a href="#text_55682">
							$subs($subscribe)
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55683">
						<a href="#text_55683">
							$module
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55684">
						<a href="#text_55684">
							$route
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55685">
						<a href="#text_55685">
							$routeContext
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55686">
						<a href="#text_55686">
							$location
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55687">
						<a href="#text_55687">
							$cache
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55688">
						<a href="#text_55688">
							$param
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55689">
						<a href="#text_55689">
							$timeout
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55690">
						<a href="#text_55690">
							$render
						</a>	
					</li>
																										<li style="width:216px" id="navi_text_55691">
						<a href="#text_55691">
							$linq
						</a>	
					</li>
											</ul>
																							<li style="width:226px" id="navi_text_55700">
						<a href="#text_55700">
							factory注入
						</a>	
					</li>
											</ul>
								</ul>
																									<li class="sin_navi_ca" style="width: 246px;" id="navi_category_13137">
								<a href="#category_13137">
									API参考
								</a>
							</li>
										<ul>
																			<li style="width:236px" id="navi_text_55701">
						<a href="#text_55701">
							多版本共存问题
						</a>	
					</li>
																<li class="sin_navi_ca" style="width:236px" id="navi_category_13126">
					<a href="#category_13126">
						基础方法/属性
					</a>
				</li>
							<ul>
																			<li style="width:226px" id="navi_text_55611">
						<a href="#text_55611">
							version
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55612">
						<a href="#text_55612">
							isDebug
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55613">
						<a href="#text_55613">
							prdtVersion
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55614">
						<a href="#text_55614">
							stringEmpty
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55615">
						<a href="#text_55615">
							noop
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55616">
						<a href="#text_55616">
							newLine
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55617">
						<a href="#text_55617">
							trace
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55618">
						<a href="#text_55618">
							isUndefined
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55619">
						<a href="#text_55619">
							isNull
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55620">
						<a href="#text_55620">
							isBoolean
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55621">
						<a href="#text_55621">
							isNullEmpty
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55622">
						<a href="#text_55622">
							isFunction
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55623">
						<a href="#text_55623">
							isNumeric
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55624">
						<a href="#text_55624">
							isString
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55625">
						<a href="#text_55625">
							isObject
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55626">
						<a href="#text_55626">
							isPlainObject
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55627">
						<a href="#text_55627">
							isArray
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55628">
						<a href="#text_55628">
							isWindow
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55629">
						<a href="#text_55629">
							isElement
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55630">
						<a href="#text_55630">
							isStringEquals
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55631">
						<a href="#text_55631">
							trim
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55632">
						<a href="#text_55632">
							replaceAll
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55633">
						<a href="#text_55633">
							toStr
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55634">
						<a href="#text_55634">
							inArray
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55635">
						<a href="#text_55635">
							removeArrayItem
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55636">
						<a href="#text_55636">
							sliceArray
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55637">
						<a href="#text_55637">
							makeAutoId
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55638">
						<a href="#text_55638">
							each
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55639">
						<a href="#text_55639">
							eachProp
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55640">
						<a href="#text_55640">
							htmlEncode
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55641">
						<a href="#text_55641">
							htmlDecode
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55642">
						<a href="#text_55642">
							urlEncode
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55643">
						<a href="#text_55643">
							urlDecode
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55644">
						<a href="#text_55644">
							clearObject
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55645">
						<a href="#text_55645">
							extend
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55646">
						<a href="#text_55646">
							clone
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55647">
						<a href="#text_55647">
							proxy
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55648">
						<a href="#text_55648">
							equals
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55649">
						<a href="#text_55649">
							datavalue
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55650">
						<a href="#text_55650">
							Event
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55651">
						<a href="#text_55651">
							isEvent
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55652">
						<a href="#text_55652">
							using
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55653">
						<a href="#text_55653">
							usingMap
						</a>	
					</li>
																										<li style="width:226px" id="navi_text_55654">
						<a href="#text_55654">
							ready
						</a>	
					</li>
											</ul>
													<li class="sin_navi_ca" style="width:236px" id="navi_category_13129">
					<a href="#category_13129">
						类
					</a>
				</li>
							<ul>
									<li class="sin_navi_ca" style="width:226px" id="navi_category_13122">
					<a href="#category_13122">
						类库
					</a>
				</li>
							<ul>
																			<li style="width:216px" id="navi_text_55581">
						<a href="#text_55581">
							bingo.Class.Base
						</a>	
					</li>
											</ul>
																							<li style="width:226px" id="navi_text_55661">
						<a href="#text_55661">
							类的定义 bingo.Class
						</a>	
					</li>
											</ul>
								</ul>
																			</ul>
		</div>
		<div class="sin_content" id="sin_content_id">
																													<h2 id="text_55576" class="sin_target">概述</h2>
<div class="sin_text">
    					<p>Git地址：<a href="http://git.oschina.net/bingoJS/bingoJS/" rel="nofollow">http://git.oschina.net/bingoJS/bingoJS</a></p>
<p>参考文档：<a href="http://bingojs.mydoc.io/" rel="nofollow">http://bingojs.mydoc.io/</a></p>
<p>库包下载：<a href="https://git.oschina.net/bingoJS/bingoJS/blob/master/bingo.full.zip" rel="nofollow">https://git.oschina.net/bingoJS/bingoJS/blob/master/bingo.full.zip</a></p>
<p>三种开发规划方式(开发模式)Demo:<a href="https://git.oschina.net/bingoJS/bingoJS/tree/master/demo" rel="nofollow">https://git.oschina.net/bingoJS/bingoJS/tree/master/demo</a></p>
<p>更新记录:<a href="http://git.oschina.net/bingoJS/bingoJS/blob/master/history.md" rel="nofollow">http://git.oschina.net/bingoJS/bingoJS/blob/master/history.md</a></p>
<p>BingoJS技术交流群：<a href="http:" rel="nofollow">172982805</a></p>
<h2>&nbsp;</h2>
<h4>1、关于bingoJS</h4>
<p>bingoJS是一个前端MV*开发框架， 致力打造最完善的浏览端JS开发框架，在双向绑定方面提取现有MV框架各种优点，并将模块化开发、按需动态加载、依赖注入、服务化等技术集成到框架，而且对现在所有框架都没任何冲突顺利兼容，让你只需简单配置就可以只关注自己业务代码的编写。</p>
<h4>2、双向绑定</h4>
<p>jQuery操作dom开发和双向绑定都是一种手段，而双向绑定可以让html与JS很好分离开来，而不用直接操作dom层，让JS专心处理业务代码（组装显示业务数据）。比如业务系统中会存在大量数据收集和提交，这些场景都非合适用绑定手段，看下面例子实现：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;
    名字：&lt;input bg-model="datas.name" /&gt;
    年龄：&lt;input bg-model="datas.age" /&gt;
    &lt;button bg-click="save"&gt;保存&lt;/button&gt;
&lt;/div&gt;
&lt;script&gt;
    var action1 = bingo.action(function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });
&lt;/script&gt;
</code></pre>
<p></p>
<h4>3、提供MV*开发模式</h4>
<p>MVC是一种开发模式，是一种代码组织和规划方式，可以对开发规范和思维的统一，对前端工程迭代，后期维护，交付变得更容易；跟现有前端MV框架比，**bingoJS**拥有最完善MV*开发模式，可以说没有任何配置就可以实现正常的业务开发：</p>
<h4>3.1、支持现在常见的MVVM开发，你可以简单定义一个action进行绑定：</h4> 
<pre><code>&lt;div bg-action="action1"&gt;
    名字：&lt;input bg-model="datas.name" /&gt;
    年龄：&lt;input bg-model="datas.age" /&gt;
    &lt;button bg-click="save"&gt;保存&lt;/button&gt;
&lt;/div&gt;
&lt;script&gt;
    var action1 = bingo.action(function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });
&lt;/script&gt;
</code></pre>
<h4>3.2、支持纯前端MV开发，这时可以认为你服务端代码和浏览端代码完全隔离，即retful+前端MV：</h4> 
<pre><code>&lt;div bg-action="action/demo/user"&gt;
    名字：&lt;input bg-model="datas.name" /&gt;
    年龄：&lt;input bg-model="datas.age" /&gt;
    &lt;button bg-click="save"&gt;保存&lt;/button&gt;
&lt;/div&gt;
&lt;script&gt;
    bingo.module('demo').action('userInfo', function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });
&lt;/script&gt;
</code></pre>
<p>如果上面代码所示，html与js代码是放一块的，如果感觉比较混乱和后期维护难，我们还可以将它们分开来，框架已经会自动帮你做这些识别：</p>
<p>view/demo/user文件</p> 
<pre><code>&lt;div bg-action="action/demo/user"&gt;
    名字：&lt;input bg-model="datas.name" /&gt;
    年龄：&lt;input bg-model="datas.age" /&gt;
    &lt;button bg-click="save"&gt;保存&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<p>action/demo/user文件</p> 
<pre><code><br>    bingo.module('demo').action('userInfo', function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });

</code></pre>
<p>你会发现它们的内容是没有任何改变，但完全可以将它们分离开来，这里还有一个route url概念，如果有兴趣可以去看说明文档</p>
<h4>3.3、支持纯前端MVC开发，这时前端MV已经不能满足你划分业务复杂度，还需再一步细分，即retful+前端MVC：</h4>
<p>view/demo/user/list文件</p> 
<pre><code>&lt;div bg-action="action/demo/user/info"&gt;
    名字：&lt;input bg-model="datas.name" /&gt;
    年龄：&lt;input bg-model="datas.age" /&gt;
    &lt;button bg-click="save"&gt;保存&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<p>action/demo/user文件</p> 
<pre><code>bingo.module('demo').controller('user', function () {

    bingo.action('list', function ($view, $ajax) {

    });

    bingo.action('info', function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });
});

</code></pre>
<p><code>如果大家细心会发现，上面无论怎么组织代码都是View与Action一一对应（即html与JS）,我们可以说成view和action，其它都是辅助</code></p>
<h4>4、按需加载</h4> 
<ul> 
 <li>首先统一前端开发动态加载的资源是什么，本框架指js文件和view模板资源（css有些人认为是，但它动态加载严重影响体验）</li> 
 <li>框架所有动态加载资源都是通过route（路由）进行前端资源url design</li> 
 <li>载模块提供一种最单纯加载机制，就是只负责加载（route转发后的地址加载资源）， 因此是兼容所</li> 
</ul>
<p>有现有的JS库，如果要合并打包也就最低限度设置即可。</p> 
<pre><code>//可以按需引用
bingo.using('scripts/plugins/jquery.transit.min.js');
bingo.using('services/userService');

bingo.module('demo').controller('user', function () {

    bingo.action('list', function ($view, $ajax) {

    });

    bingo.action('info', function ($view, $ajax) {

        var datas = {
            name: '',
            age: ''
        };

        $view.save = function () {
            $ajax('/rest/save').param(datas).post();
        };

    });
});

</code></pre>
<p>可以看见，它们组织思维跟后端代码组织思维很相像，这样开发人员很简单就能过度来开发；</p>
<h4>5、兼容性</h4>
<p>在JS方面可以说完全兼容到IE6；在dom管理方除了核心编译部分用了原生外，其它都几乎依赖jQuery写的，所以取决于jQuery版本的兼容;</p>
			</div>

																										<h2 id="category_13121">启动</h2>
																								<h3 id="text_55579" class="sin_target">hello world</h3>
<div class="sin_text">
    					<h4>1、例子代码</h4> 
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义helloworld
        var helloworld = 'helloworld bingoJS';
        //定义time
        var time = new Date().toString();
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div&gt;
        &lt;!--绑定helloworld--&gt;
        {{helloworld}}
    &lt;/div&gt;
    &lt;!--绑定time--&gt;
    &lt;div bg-text="time"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h4>2、运行效果</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/16195218_PJ4r.png" alt="运行效果" title="运行效果"></p>
<h4>3、例子说明</h4>
<p>从上面的代码中，只是显示helloworld和当前时间，我们看到在通常的 HTML 代码当中，引入了一些指令**{{}}** 和 <strong>bg</strong>，这些就是模板机制，它不光完成数据渲染的工作，还实现了数据绑定的功能。</p>
<p>在页面里只要引用jquery和bingo.js， 等页面加载完成后就会自动启动bingoJS，对html dom进行编译，根据有效的指令进行相应的绑定处理。</p>
<p><a href="http://git.oschina.net/bingoJS/bingoJS/tree/master/demo" rel="nofollow">下载demo代码</a></p>
			</div>

																						<h3 id="text_55580" class="sin_target">action&amp;view</h3>
<div class="sin_text">
    					<h4>1、例子代码</h4> 
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义action1
        var action1 = bingo.action(function ($view) {
            //$view为传入的视图

            //向view定义一个变量time
            $view.time = new Date().toString();

            //向view定义一个方法updateTime
            $view.updateTime = function () {
                $view.time = new Date().toString();
            };

        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        &lt;div&gt;
            &lt;!--time--&gt;
            {{time}}
        &lt;/div&gt;
        &lt;!--绑定updateTime单击事件--&gt;
        &lt;input type="button" value="刷新时间"
            bg-click="updateTime" /&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h4>2、运行效果</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/16194927_Jssl.png" alt="运行效果" title="运行效果"></p>
<h4>3、例子说明</h4>
<p>从上面的代码中，在页面显示当前时间和一个“刷新时间”按钮，当点击按钮后，页面中时间的也会改变。</p>
<p>在HTML中定义一个**bg-action**指令与**action1**联系起来，这时HTML中**bg-action**指令的**div**及子孙节点会生成一个新的**$view**，并传入到**action1**中，而我们要做的是在action中向$view定义变量或方法，同时在 HTML 中利用**bg**指令绑定到相应的变量或方法，同时在 HTML 中的本身的 DOM 层级结构，被 <strong>bg</strong> 利用起来，直接作为它的内部机制中，上下文结构的判断依据。其它的，也同样写一些 js 代码，里面重要的是作一些数据的操作，事件的绑定定义等。这样，数据的变化就会和页面中的 DOM 表现联系起来。一旦这种联系建立起来，也即完成了我们所说的“双向绑定”。然后，这里说的“事件”，除了那些“点击”等通常的 DOM 事件之外，我们还更关注“数据变化”这个事件。这样一来，我们就可能从面向操作DOM编程转到面向业务编程。</p>
<h4>4、$view 与 action 关系</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/18093215_Hcz3.png" alt="$view 与 action 关系" title="$view 与 action 关系"></p>
<p><a href="http://git.oschina.net/bingoJS/bingoJS/tree/master/demo" rel="nofollow">下载demo代码</a></p>
			</div>

																														<h2 id="category_13127">数据绑定</h2>
																								<h3 id="text_55655" class="sin_target">绑定与同步</h3>
<div class="sin_text">
    					<pre><code>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义action1
        var action1 = bingo.action(function ($view) {
            
            $view.user = {
                name: '张三',
                age:20
            };

            setTimeout(function () {
                //重新设置user
                $view.user = {
                    name: '李四',
                    age: 23
                };

                //刷新view
                $view.$update();

            }, 1000);

        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        姓名:{{user.name}}, 年龄:{{user.age}}
        &lt;br /&gt;
        姓名(第一次):{{: user.name}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h4>运行效果</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/17134340_NSQO.png" alt="运行效果" title="运行效果"></p>
<p>在html代码中，我们可以看到 <strong>{{user.name}}</strong> 和 <strong>bg-html</strong>指令，其实它们作用是一样的，都是直接显示绑定数据的内容（HTML内容），只不过谁在当时场景使用比较方便而已；再来看第二个 <strong>{{: user.name}}</strong> 它与第一个相比是前面多了一个 <strong>:</strong> 符号，它表示只做输出处理不做绑定（即以后数据发改变了，它也不会改变），这个指令多用于 <strong>bg-for</strong> 内容模板里（只用于显示数据），以提高处理效率；</p>
<p>在 <strong>JS</strong> 代码中，我们先初始**user**的内容， 并1秒后修改**user**的内容，并手动调动**$view.$update**()，将数据同步到**$view**，这样明显不够智能，接下来我们可以对**setTimeout**封装一下：</p> 
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;

        bingo.factory('$timeout', function ($view) {

            return function (callback, time) {
                return setTimeout(function () {
                    if ($view.isDisposed) return;
                    callback &amp;&amp; callback();
                    $view.$update();
                }, time || 1);
            };

        });

        //定义action1
        var action1 = bingo.action(function ($view, $timeout) {
            
            $view.user = {
                name: '张三',
                age:20
            };

            $timeout(function () {
                //重新设置user
                $view.user = {
                    name: '李四',
                    age: 23
                };

            }, 1000);

        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        姓名:{{user.name}}, 年龄:&lt;span bg-html="user.age"&gt;&lt;/span&gt;
        &lt;br /&gt;
        姓名(第一次):{{: user.name}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>在这里我们把**setTimeout**封装成了一个**$timeout**(factory), 它帮我做了**$update**；这时我们在**action中**使用注入的**$timeout**时就不用再手动**$update**, 许多地方（如事件绑定）我们都是这样处理的这样会变得更智能；</p>
			</div>

																						<h3 id="text_55656" class="sin_target">观察者(observer)</h3>
<div class="sin_text">
    					<p>本框架使用观察者设计模式会为每个**$view**创建一个相应的**观察者**(observer)，用来观察数据的改变情况；在开发过程中可用**$subs**（$subscribe）订阅相关数据使用情况，然后使用**$view.$update**(或$view.$publish)发布信息，如何实现请看下面代码：<br> </p>
<pre><code><br>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义action1
        var action1 = bingo.action(function ($view, $subs, $timeout) {
            
            //初始user数据
            $view.user = {
                name: '张三',
                age:20
            };

            //订阅$subscribe, 这里订阅$view.user.name
            $subs(function () { return $view.user.name; }, function (value) {
                //如果$view.user.name不是'张三', 将$view.user.age设为23
                if (value != '张三')
                    $view.user.age = 23;
            });

            setTimeout(function () {

                //设置$view.user.name为'李四'
                $view.user.name = '李四';

                //向订阅发布信息（同步数据）
                $view.$update();//等效于$view.$publish()

            }, 1000);

        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        姓名:{{user.name}}, 年龄:{{user.age}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<br>例子中， 先用**$subs**订阅**$view.user.name**观察它的使用情况， 然后个修改**$view.user.name**的值并使用**$view.$update**请求同步数据（其实是向订阅发布信息），这时观察到**$view.user.name**值已经不是‘**张三**’了，最后设置**$view.user.age**为**23**
<p></p>
			</div>

																						<h3 id="text_55657" class="sin_target">variable变量</h3>
<div class="sin_text">
    					<p>如上面所说，当我们要同步**$view**数据时，“**观察者**”会向所有订阅发布信息，如果订阅很多时会影响整体性能，这时框架提供另一种同步数据机制，数据到绑定点到点同步，这就是**variable**变量使用场景<br> </p>
<pre><code><br>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义action1
        var action1 = bingo.action(function ($view, $var) {

            $view.userName = $var('张三');//等效于bingo.variable('', null, $view);
            
            setTimeout(function () {

                $view.userName('李四');

            }, 1000);

        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        姓名:{{userName}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p></p>
<p>上面代码演示 <strong>$var</strong> (**variable**)使用，你会发现数据不用手动**$update**就可以同步到**$view**；与普通**JS变量**不同的是**variable**已经集成了观察特性:</p> 
<pre><code>//定义action1
var action1 = bingo.action(function ($view, $var) {

    $view.userName = $var('张三'); //等效于bingo.variable('', null, $view);
            
    setTimeout(function () {

        //修改userName值
        $view.userName('李四');

    }, 1000);


    //读取userName值
    var test = $view.userName();

    //观察是否有改变
    $view.userName.$subs(function (value) {
    });

    //观察是否有赋值(不论有没改变)
    $view.userName.$assign(function (value) {
    });

    //可以改变get/set
    $view.userName.$set(function (value) { this.value = value; });
    $view.userName.$get(function () { return this.value; });

    //也可以使用$subs观察
    $subs(function () { return $view.userName; }, function (value) {

    });

});
</code></pre>
<p>上面代码说明**variable**的主要特性，而且框架内部对些变量做了专门优化，提高同步数据性能，原因它已经知道什么时候已经改变了，不像**$update**那样去检查整个**$view**的绑定数据情况；</p>
			</div>

																						<h3 id="text_55658" class="sin_target">model</h3>
<div class="sin_text">
    					<pre><code>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        //定义action1
        var action1 = bingo.action(function ($view, $model, $subs) {

            //定义user model
            $view.user = $model({
                name: '张三',
                age: 20
            });

            setTimeout(function () {

                //设置user值
                $view.user.fromObject({
                    name: '李四',
                    age: 23
                });

            }, 1000);


        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与action1连接, 形成一个新view--&gt;
    &lt;div bg-action="action1"&gt;
        姓名:{{user.name}}, 年龄:{{user.age}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>上面演示 <strong>$model</strong> 使用，**$model**可以认为是**variable**的集合体（批量操作），它的属性使用方法**variable**一样的</p> 
<pre><code>//定义action1
var action1 = bingo.action(function ($view, $model, $subs) {

    //定义user model
    $view.user = $model({
        name: '张三',
        age: 20
    });

    setTimeout(function () {

        //设置user值
        $view.user.fromObject({
            name: '李四',
            age: 23
        });

    }, 1000);

    //返回JS object
    var user = $view.user.toObject();

    //$view.user.name是一个variable变量
    $view.user.name.$subs(function (value) { });

    //也可以使用$subs观察
    $subs(function () { return $view.user; }, function (value) {

    });
});
</code></pre>
<p>上面代码说明**$model**的主要特性，也就提供了**formObject**和**toObject**两个方法实现跟JS object转换；</p>
			</div>

																														<h2 id="category_13130">MVC开发模式</h2>
																								<h3 id="text_55662" class="sin_target">基础组成元素</h3>
<div class="sin_text">
    					<p>在上面例子中， <strong>action</strong>和**view**是一 一对应；而在**MVC开发模式**中我们要使用到**module**、**controller**、**action**和**view**四种要素，先用下面代码看看它们之间的关系和如何使用；<br> </p>
<pre><code><br>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;helloworld&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;

        //定义demo模块
        bingo.module('demo', function () {

            //定义user控制器
            bingo.controller('user', function () {

                //向user控制器定义userInfo
                this.userInfo = bingo.variable(null);

                //定义user/list action
                bingo.action('list', function ($view) {

                    //定义用户列表
                    $view.userList = [{ id: 1, name: '张三' }, { id: 2, name: '李四' }];

                    //取得当前controller(user控制器)
                    var controller = this.conroller;
                    //定义改变user方法
                    $view.changeUser = function (user) {
                        //设置新的user到controller.userInfo
                        controller.userInfo(user);
                    };
                });

                //定义user/info action
                bingo.action('info', function ($view, $subs) {
                    
                    //定义$view要显示的变量
                    $view.userId = '';
                    $view.userName = '';

                    //取得当前controller(user控制器)
                    var conroller = this.conroller;

                    //观察conroller.userInfo
                    $subs(function () { return conroller.userInfo; }, function (userInfo) {
                        //观察到conroller.userInfo改变, 将数据显示
                        $view.userId = userInfo.id;
                        $view.userName = userInfo.name;
                    });

                });

            });

        });

    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--与demo/user/list连接, 形成一个新view--&gt;
    &lt;div bg-action="action/demo/user/list"&gt;
        &lt;div bg-for="item in userList"&gt;
            &lt;span&gt;{{: item.id}}&lt;/span&gt;
            &lt;span&gt;{{: item.name}}&lt;/span&gt;
            &lt;span&gt;
                &lt;input type="button" value="查看"
                       bg-click="changeUser(item)" /&gt;
            &lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!--与demo/user/info, 形成一个新view--&gt;
    &lt;div bg-action="action/demo/user/info"&gt;
        &lt;div&gt;
            &lt;span&gt;当前用户信息: &lt;/span&gt;
            &lt;span&gt;id: {{userId}}&lt;/span&gt;
            &lt;span&gt;name: {{userName}}&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p></p>
<h4>2、运行效果</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/17105211_6mVN.png" alt="运行效果" title="运行效果"></p>
<h4>3、例子说明</h4>
<p>到现在为止，可能上面例子有些复杂，但总体实现效果是**显示所有用户数据**，并点击**查看**时可以**显示相关的用户信息**。而在这里主要想说明**module**、**controller**、**action**、**view**之间的关系和如何使用，从代码我们可以得出它们关系如下：<br><img src="https://static.oschina.net/uploads/img/201505/15225353_hp0I.png" alt="MVC关系" title="MVC关系"></p>
<p><strong>JS</strong>代码中，我们定义**demo/user/list**和**demo/user/info**两个**action**, 并两个**action**之间使用**controller**的**userInfo**通讯; 在user/list中设置点击“**查看**”时将用户信息设置到**userInfo**, 而在**user/info**中就会观察到**userInfo**改变并处理相关的显示;</p>
<p>而在实际开发中，我们会大量处理到这种场景，比如上面例子中的用户功能，可能还会新建用户，修改用户等，都会这种场景；</p>
			</div>

																						<h3 id="text_55663" class="sin_target">route（路由）</h3>
<div class="sin_text">
    					<h4>1.route定义与解释过程</h4>
<p>上面代码中，有这么一段：<br> </p>
<pre><code><br>&lt;div bg-action="action/demo/user/info"&gt;
</code></pre>
<br>
<strong>action/demo/user/info</strong>意思是使用**demo/user/info**这个**action**，那么程序是怎么知道它使用**demo**(module).**user**(controller).**info**(action)呢？我们先来看看action route定义：
<br> 
<pre><code><br>    //定义action资源路由
    bingo.route('action', {
        //route url，匹配和解释时用
        url: 'action/{module}/{controller}/{action}',
        //生成新的目标地址，当route url匹配后
        toUrl: 'modules/{module}/controllers/{controller}.js',
        //route参数默认值
        defaultValue: { module: 'system', controller: 'user', action: 'list' }
    });
</code></pre>
<br>当route url为**action/demo/user/info**时，框架会去route表查找到匹配的route，正如action route的定义，匹配到了这个route，接下来对url进行解释：
<br>1. 认为用**{ }**包括起来部分为路由参数
<br>2. 从route url解释出module、controller、action三个路由参数分别为**demo**、**user**、**info**
<br>3. 框架查询是否有定义**demo.user.info**
<br>4. 如果没有定义，按照**toUrl**规则和路由参数重新组织出来的**url**加载资源
<br>5. 将**demo.user.info**绑定**bg-action**
<p></p>
<p><code>**注意**：如果在route表没有查找到匹配时，route器会把传入的url原原本本的返回</code></p>
<p>如传入scripts/plu/flt.js，结果route表没有，这时就会返回scripts/plu/flt.js</p>
<h4>2.框架三个默认路由</h4>
<p>为什么**action/demo/user/info**要加**action**开头呢？原因同后端相比，前端会有几种资源类型：**view**、**action**、**service**等，请看下面**route**定义:<br> </p>
<pre><code><br>//设置view资源路由
bingo.route('view', {
    //优先级, 越大越前, 默认100
    priority: 100,
    //路由url, 如: view/system/user/list
    url: 'view/{module}/{controller}/{action}',
    //路由到目标url, 生成:modules/system/views/user/list.html
    toUrl: 'modules/{module}/views/{controller}/{action}.html',
    //变量默认值, 框架提供内部用的变量: module, controller, action, service
    defaultValue: { module: 'system', controller: 'user', action: 'list' }
});

//设置action资源路由
bingo.route('action', {
    url: 'action/{module}/{controller}/{action}',
    toUrl: 'modules/{module}/controllers/{controller}.js',
    defaultValue: { module: 'system', controller: 'user', action: 'list' }
});

//设置service资源路由
bingo.route('service', {
    url: 'service/{module}/{service}',
    toUrl: 'modules/{module}/services/{service}.js',
    defaultValue: { module: 'system', service: 'user' }
});
</code></pre>
<br>上面是本框架三个默认route的定义，并最终文件资源结构如下：
<p></p>
<p><img src="https://static.oschina.net/uploads/img/201505/18154714_GJFJ.png" alt="组织资源结构" title="组织资源结构"></p>
<p><code>当然我们可以完全不使用默认route，可以重新组织自己要的route，这也只是框架一种提议而已</code></p>
<h4>3.路由其它问题</h4> 
<ol> 
 <li>路由查询顺序是按路由定义的priority属性决定，此属性越大越先查询</li> 
 <li>如果路由重复定义（路由名称相同），后面定义会把之前定义的复盖掉（如同修改的效果）</li> 
 <li><strong>module</strong>、**controller**、**action**、**service**这四个路由参数对框架有特殊意义的，除此之外还可以使用其它名称作为路由参数名称，如：userinfo/demo/user/{id}</li> 
</ol>
			</div>

																						<h3 id="text_55664" class="sin_target">按需加载开发</h3>
<div class="sin_text">
    					<p>了解route后，我们就可以使用按需加载开发了。下面用user功能来举例，主要说明整个开发过程:</p>
<h4>文件资源结构:</h4>
<p><img src="https://static.oschina.net/uploads/img/201505/19093152_v9Ly.png" alt="文件资源结构" title="文件资源结构"></p>
<h4>主页:</h4>
<p>使用**bg-route**加载view/demo/user/list<br> </p>
<pre><code><br>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;按需加载&lt;/title&gt;
    &lt;script src="scripts/jquery-1.8.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="scripts/bingo.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--使用route加载demo/user/list--&gt;
    &lt;div bg-route="view/demo/user/list"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p></p>
<h4>view/demo/user/list</h4>
<p>使用**bg-action**连接到view/demo/user/list, 请看demo/user控制器代码<br> </p>
<pre><code><br>&lt;div bg-action="action/demo/user/list"&gt;
    {{: title}}
    &lt;div bg-for="item in userList"&gt;
        &lt;div&gt;
            &lt;span&gt;{{: item.id}}&lt;/span&gt;
            &lt;span&gt;{{: item.name}}&lt;/span&gt;
            &lt;span&gt;
                &lt;input type="button" value="查看"
                       bg-click="showForm(item)" /&gt;
            &lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p></p>
<h4>view/demo/user/form</h4>
<p>使用**bg-action**连接到view/demo/user/form, 请看demo/user控制器代码<br> </p>
<pre><code><br>&lt;div bg-action="action/demo/user/form" style="color:blue;"&gt;
    {{: title}}
    &lt;div&gt;
        &lt;span&gt;id: {{: userInfo.id}}&lt;/span&gt;
        &lt;span&gt;name: {{: userInfo.name}}&lt;/span&gt;
    &lt;/div&gt;
    &lt;input type="button" value="返回" bg-click="backList" /&gt;
&lt;/div&gt;
</code></pre>
<p></p>
<h4>userService</h4>
<p>定义userService, 在demo/user/list中注入, 请看demo/user控制器代码<br> </p>
<pre><code><br>(function () {
    'use strict';

    bingo.module('demo').service('userService', function ($view) {

        return {
            getUserDatas: function () {
                return [{ id: 1, name: '张三' }, { id: 2, name: '李四' }];
            }
        };

    });

})();
</code></pre>
<p></p>
<h4>demo/user 控制器</h4>
<p>//下面主要说明如果引用和使用**service**, 如何使用**$location**进行跳转，如何使用**$cache**传送参数<br> </p>
<pre><code><br>//引用userService
bingo.using('service/demo/userService');

(function () {
    'use strict';

    bingo.module('demo').controller('user', function () {

        bingo.action('list', function ($view, $location, $param, userService) {
            $view.title = '用户列表';

            //从userService取得用户数据
            $view.userList = userService.getUserDatas();

            $view.showForm = function (user) {
                //设置user信息到param
                $param('userinfo', user);
                //连接到user/form
                $location.href('view/demo/user/form');
            };
        });

        bingo.action('form', function ($view, $location, $param) {
            $view.title = '用户信息'

            //从$param取得user信息,
            //注意$param userinfo会自动清除，即再次使用$param('userinfo')已经为undefined
            $view.userInfo = $param('userinfo');

            $view.backList = function () {
                //返回user/list
                $location.href('view/demo/user/list');
            };

        });

    });

})();
</code></pre>
<p></p>
<h4>效果图</h4>
<p>list:</p>
<p><img src="https://static.oschina.net/uploads/img/201505/19095637_ju3s.png" alt="list效果图" title="list效果图"></p>
<p>form:</p>
<p><img src="https://static.oschina.net/uploads/img/201505/19095357_NsQ7.png" alt="form效果图" title="form效果图"></p>
<h4>总的来说是这样的过程：</h4> 
<ol> 
 <li>主页面使用**bg-route**加载view/demo/user/list模板</li> 
 <li>view/demo/user/list模板中使用**bg-action**连接到action/demo/user/list代码</li> 
 <li>在action/demo/user/list代码中使用**userServer.getUserDatas**取得数据源</li> 
 <li>在action/demo/user/list代码中使用**$param**设置要传送的参数</li> 
 <li>在action/demo/user/list代码中使用**$location**中转到view/demo/user/form</li> 
 <li>view/demo/user/form模板中使用**bg-action**连接到action/demo/user/form代码</li> 
 <li>在action/demo/user/form代码中使用**$param**取得传送过的参数并设置到$view显示出来</li> 
</ol>
<p>具体动态加载请参考指令**bg-route**， 动态编译：**$complie**</p>
<p><a href="http://git.oschina.net/bingoJS/bingoJS/tree/master/demo" rel="nofollow">下载demo代码</a></p>
			</div>

																						<h3 id="text_55665" class="sin_target">使用其他框架或库</h3>
<div class="sin_text">
    					<p>首先声明，本框架原理上不跟任何框架或库冲突，除非名称有冲突（这个不可能吧）；原因框架只做加载操作和保障，并在url上做route控制而已，请看下面例子：<br> </p>
<pre><code><br>//引用userService
bingo.using('service/demo/userService');

//引用plupload.full.min.js
bingo.using('scripts/plugins/plupload_2_1_2/js/plupload.full.min.js', function () {
    //引用plupload.full.min.js的i18n数据
    bingo.using('scripts/plugins/plupload_2_1_2/js/i18n/zh_CN.js');
});


var action1 = bingo.action(function ($view) {
    var jBtn = $view.$getNode('.button');

    var uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: jBtn.get(0),
        container: jBtn.parent().get(0),
        url: 'upload.jsp',
        max_file_size: '10m',
        filters: {
            max_file_size: '10m',
            mime_types: 'jpg'
        },
        flash_swf_url: 'scripts/plugins/plupload_2_1_2/js/Moxie.swf',
        silverlight_xap_url: 'scripts/plugins/plupload_2_1_2/js/Moxie.xap'
    });

});

</code></pre>
<br>上面代码，主要使用了**plupload**进行文件上传，在这里说明了框架只是加载而已，并没有做太多的事情，而且是通过route进行url design
<p></p>
			</div>

																																						<h2 id="text_55577" class="sin_target">多版本共存</h2>
<div class="sin_text">
    					<p>处理bingo多版本共存问题, 以下这种方式处理共存问题<br> </p>
<pre><code><br>(function(bingo){

    bingo.trim('');

})(bingoV1); //bingo或bingoV1或bingoV1_1两种，注意根据版本引用
</code></pre>
<p></p>
<p>bingoJS会为每个版本生成两个相应的版本对象：<br>如bingo1.1就会生成bingoV1和bingoV1_1两个对象<br>如bingo1.2就会生成bingoV1和bingoV1_2两个对象<br>如此类推</p>
<p>在上面例子中可以看到我们是使用bingo1.*开发</p>
			</div>

																																		<h2 id="text_55578" class="sin_target">demo</h2>
<div class="sin_text">
    					<p><a href="http://git.oschina.net/bingoJS/bingoJS/tree/master/demo" rel="nofollow">下载demo代码</a></p>
<h4>start1</h4>
<p>演示简单的view —&gt; action规划方式</p>
<p><a href="http://bingojs.oschina.mopaas.com/demo/start1/index.html" rel="nofollow">运行效果</a></p>
<h4>start2</h4>
<p>演示一个view文件 对应 一个action文件规划方式</p>
<p><a href="http://bingojs.oschina.mopaas.com/demo/start2/index.html" rel="nofollow">运行效果</a></p>
<h4>start3</h4>
<p>演示常用的MVC规划方式</p>
<p><a href="http://bingojs.oschina.mopaas.com/demo/start3/index.html" rel="nofollow">运行效果</a></p>
<h4>bootstrap</h4>
<p>如何结合bootstrap只需简单搭建bingoJS就可以正常开发业务</p>
<p><a href="http://bingojs.oschina.mopaas.com/demo/bootstrap/index.html" rel="nofollow">运行效果</a></p>
<p><code>注意:只能在web服务环境才能正常演示, 原因是浏览器有可能不支持本地XHR加载</code></p>
			</div>

																										<h2 id="category_13135">开发参考</h2>
																								<h3 id="text_55696" class="sin_target">概述</h3>
<div class="sin_text">
    					<p>到这里，bingoJS如何启动，什么是数据绑定，什么是route，如果动态按需加载开发，这些基础已经有，相信可以用于实际开发中了。</p>
<p><code>从这里开始，主要是开发过程中要使用的一些参考文档，一开始也不用深入研究，</code><br><code>只要了解一下就可以了，在开发用到时作为参考的一些资料</code></p>
<p>#### 1、bingoJS的相关概念：<br>- <strong>module</strong> ，代码的组织单元，其它东西都是在定义在具体的模块中的。<br>- <strong>controller</strong> ，控制action，即是一种业务封装概念，又体现了项目组织的层级结构。<br>- <strong>action</strong> ，业务概念，可能会用到多个模块。<br>- <strong>service</strong> ，仅在数据层面实现特定业务功能的代码封装。<br>- <strong>command</strong> ，与 DOM 结构相关联的，特定功能的封装形式。<br>- <strong>filter</strong> ，改变输入数据的一种机制。<br>- <strong>factory</strong> ，定义依赖，让要使用时随时可以注入。</p>
<h4>2、bingoJS的相关关系：</h4>
<p><img src="https://static.oschina.net/uploads/img/201506/04084644_7QsN.png" alt="相关概念与关系" title="相关概念与关系"></p>
<p>全局的定义代码：<br> </p>
<pre><code><br>//定义action1 action
var action1 = bingo.action(function ($view) {
});

//定义systemSrv service
bingo.service('systemSrv', function ($view) {
});

//定义bg-action command
bingo.command('bg-action', function () {
    return ['$view', '$attr', function ($view, $attr) {
    }];
});

//定义text filter
bingo.filter('text', function ($view) {
    return function (value, para) {
        return value;
    };
});

//定义$node factory
bingo.factory('$node', function (node) {
    return $(node);
});
</code></pre>
<p></p>
<p>模块的定义代码：<br> </p>
<pre><code><br>//定义demo module
bingo.module('demo', function () {

    //定义demo/user controller
    bingo.controller('user', function () {

        //定义demo/user/list action
        bingo.action('list', function ($view) {
        });

        //定义demo/user/info action
        bingo.action('info', function ($view) {
        });

    });

    //定义demo/systemSrv service
    bingo.service('systemSrv', function ($view) {
    });

    //定义demo/bg-action command
    bingo.command('bg-action', function () {
        return ['$view', '$attr', function ($view, $attr) {
        }];
    });

    //定义demo/text filter
    bingo.filter('text', function ($view) {
        return function (value, para) {
            return value;
        };
    });

    //定义demo/$node factory
    bingo.factory('$node', function (node) {
        return $(node);
    });
});

</code></pre>
<p></p>
			</div>

																						<h3 id="text_55697" class="sin_target">定义模块</h3>
<div class="sin_text">
    					<p>总的来说，模块是组织业务的一个框框，在一个模块当中定义多个服务、控制器、模板指令等都可以组织到一个模块里。当你引入了一个模块的时候，就可以使用这个模块提供的一种或多种服务了。</p>
<p>定义模块的方法是使用 <strong>bingo.module</strong> 。调用时声明了一个模块，并定义了“声明模块化”函数。<br> </p>
<pre><code><br>  var module1 = bingo.module('MyModule', function(){
      //以下定义都是属于'module1'

     bingo.service('MyService', fucntion(){});
     bingo.action('MyAction', fucntion(){});

  });
</code></pre>
<br>这段代码定义了一个叫做 
<strong>MyModule</strong> 的模块， 
<strong>module1</strong> 这个引用可以在接下来做其它的一些定义，比如定义服务：。
<br> 
<pre><code><br>  var module1 = bingo.module('MyModule', function(){
      //以下定义都是属于'module1'
  });
  module1.service('MyService', fucntion(){});
  module1.action('MyAction', fucntion(){});
</code></pre>
<br>其它前两段代码实现的效果都是一样的，定义一个模块**MyModule**，并在**MyModule**下定义服务**MyService**和动作**MyAction**
<p></p>
			</div>

																<h3 id="category_13128">服务service</h3>
																						<h4 id="text_55659" class="sin_target">概述</h4>
<div class="sin_text">
    					<p>原则上服务可以返回定义任意对象，并且走的是注入流程，所以支持参数注入；bingo原意是将服务定位于为写action业务时提供辅助服务，比如一些重用性的代码，数据远程管理等；在下面定义的用户服务，提供用户相关的一些辅助方法：</p> 
<pre><code>bingo.service('userService', function($view, $ajax){
   
   return {
      loadUsers:function(callback){
         $ajax('rest/user/list').success(function(rs){ callback &amp;&amp; callback(rs); }).post();
      },
      isLogin:function(){....}
   };

});
</code></pre>
<p>这样就可以在action里使用了：<br> </p>
<pre><code><br>bingo.using('service/userService');//注意这里要定义相关路由

var action1 = bingo.action($view, userService){
   var userList = null;

   $view.onInitData(function(){
     userService.loadUsers(function(datas){ userList = datas; });
   });

});
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55660" class="sin_target">定义与使用</h4>
<div class="sin_text">
    					<p>服务定义很简单，就是定义服务名称和一个注入方法并返回任意对象即可以了：<br> </p>
<pre><code><br>bingo.service('userService', function($view, $ajax){

   return {
      loadUsers:function(callback){
         $ajax('rest/user/list').success(function(rs){ callback &amp;&amp; callback(rs); }).post();
      },
      isLogin:function(){....}
   };

});
</code></pre>
<p></p>
<p>服务是分为全局和模块两使用范围，即全局服务无论哪此模块都能使用，模块服务只提供模块本身使用（如果要使用其他模块的可以使用$module）,上面代码定义的是全局服务，下面代码看看如果定义模块服务：<br> </p>
<pre><code><br>bingo.module('system', function(){
   bingo.service('userService', fucntion($view){....});
});
</code></pre>
<p></p>
<p>这时只能在同一模块action才能直接使用：<br> </p>
<pre><code><br><br>bingo.using('service/system/userService');//如果不同一个JS定义，要使用using动态加载

bingo.module('system', function(){
  bingo.action('userList', function($view, userService){
    
  });
});
</code></pre>
<br>如上代码，**action**和**userService**都同属于**system**模块，所才能直接注入使用
<p></p>
<p>如果其它模块要使用system/userServer服务，只能通过**$module**来间接使用：<br> </p>
<pre><code><br>bingo.using('service/system/userService');//如果不同一个JS定义，要使用using动态加载

//定义一个全局action
var action1 = bingo.action(function($view, $module){
  var userService = $module('system').$service('userService');

});
</code></pre>
<p></p>
			</div>

																						<h3 id="category_13131">模板指令command</h3>
																<h4 id="category_13124">模板指令</h4>
																						<h5 id="text_55589" class="sin_target">概述</h5>
<div class="sin_text">
    					<p>前面讲了数据绑定之后，现在可以单独讲讲模板了。</p>
<p>作为一套能称之谓“模板”的系统，除了能干一些模板的常规的事之外（好吧，即使是常规的逻辑判断现在它也做不了的），配合作用域 <strong>$view</strong> 和 <strong>bg</strong> 的数据双向绑定机制。</p>
			</div>

																						<h5 id="text_55590" class="sin_target">bg-action</h5>
<div class="sin_text">
    					<p><strong>bg-action</strong>动作指令，用于将view和action关联起来，关联有以下二种方式：</p> 
<ul> 
 <li>直接与一个action关联起来</li> 
 <li>通过route url关联起来，以实现MVC方式开发</li> 
</ul>
<h4>1、直接与一个function关联起来</h4> 
<pre><code>&lt;div bg-action="action1"&gt;
    &lt;p bg-text="hello"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    //定义contoller
    var action1= bingo.action(function ($view) {
        //定义view的hello变量, 并设置值
        $view.hello = 'hello world!';
    });
&lt;/script&gt;
</code></pre>
<p>如上面代码， 我们定义了一个action1，然后直接用bg-action，使view与action关联起来。</p>
<h4>2、通过route url关联起来，以实现MVC方式开发</h4> 
<pre><code>&lt;div bg-action="action/dome/user/list"&gt;
    &lt;p bg-text="hello"&gt;&lt;/p&gt;
&lt;/div&gt;
</code></pre>
<p>这里我们定义一个route url方式使view与action关联起来，这种方式将会根据route内容决定对应的action js文件按需加载，可以使view tmpl与action js一一对应开发</p>
			</div>

																						<h5 id="text_55591" class="sin_target">bg-action-add</h5>
<div class="sin_text">
    					<p>添加模板指令bg-action-add, 用于添加多个action, 其他与bg-action相同<br> </p>
<pre><code><br>&lt;div bg-action="action1" bg-action-add="action2"&gt;
    &lt;div bg-action-add="action3"&gt;&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55592" class="sin_target">bg-route</h5>
<div class="sin_text">
    					<p><strong>bg-route</strong>通过route url加载相应模板文件：</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-name="main"&gt;&lt;/div&gt;
&lt;a href="#view/demo/user/list" bg-target="main"&gt;测试1&lt;/a&gt;
</code></pre>
<p><strong>bg-route</strong>用法有点像iframe, 我们可以a href指url和设置bg-target, 如果控制加载内容；</p>
<h4>route url参数：</h4>
<p>为了不跟正常url参数冲突，route url参数使用格式：$aaa:111$bbb:2，它的意思如?aaa=111&amp;bbb=2，我们使用如下代码：<br> </p>
<pre><code><br>&lt;div bg-route="view/demo/user/list$aaa:111$bbb:2" bg-name="main"&gt;&lt;/div&gt;
&lt;a href="#view/demo/user/list$aaa:111$bbb:2" bg-target="main"&gt;测试1&lt;/a&gt;
</code></pre>
<br>当然我们也可以用方法来生成route url如下：
<br> 
<pre><code><br>  var url = bingo.routeLink('view', {controller:'user', action:'list', aaa:111, bbb:2});
  url === 'view/demo/user/list$aaa:111$bbb:2';
</code></pre>
<p></p>
<h4>route url参数获取：</h4>
<p>我们可以通过$location来获取route url相关参数，详细请参考$location：<br> </p>
<pre><code><br>  var action1 = bingo.action($view, $location){
     var p = $loctaion.params();//获取bg-route的参数
     var url = $loction.url();//route url
     $location.href('view/demo/user/info'); //链接到
     $location.reload()//或重新加载
  };
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55593" class="sin_target">bg-route-loaded</h5>
<div class="sin_text">
    					<p><strong>bg-route-loaded</strong>处理bg-route加载完成：</p> 
<pre><code>var lcLoad = function(){
    var location = this;
    var url = location.url();
};
&lt;div bg-route="view/user/form1" bg-name="main"
            bg-route-load="lcLoad"&gt;
</code></pre>
			</div>

																						<h5 id="text_55594" class="sin_target">bg-render / bg-for</h5>
<div class="sin_text">
    					<p>这是循环指令或叫render指令，因为它支持render模板，详情可以参考$render;</p>
<p>定义模板的内容主要有三种方式：<br> - 在**html**需要的地方直接写字符串;<br> - 通过**url**引用同域的内容文件;<br> - 使用**script**标签定义的“内部内容”;</p>
<h4>1、在**html**需要的地方直接写字符串：</h4> 
<pre><code>&lt;select bg-tmpl="item in list"&gt;
    &lt;option value="{{: item.id}}"&gt;text_{{: item.text | text}}&lt;/option&gt;
&lt;/select&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view) {
        $view.list = [{ id: 1, text: "111" }, { id: 2, text: "222" }];
    });
&lt;/script&gt;
</code></pre>
<p>如果上面代码， select内部html为模板内容， {{: }}为模板输出标签, 当然可以{{ }}标签， 但{{ }}为绑定标签，为了支持绑定, 性能比较慢，而{{: }}为模板直接输出标签，没有绑定能力，性能是高率的；</p>
<h4>2、通过url引用同域的内容文件：</h4> 
<pre><code>&lt;select bg-foreach="item in list tmpl=tmpl_tmpl.html"&gt;&lt;/select&gt;
</code></pre>
<p>远程加载tmpl_tmpl.html文件</p>
<h4>3、使用 script 标签定义的“内部内容”：</h4> 
<pre><code>&lt;select bg-foreach="item in list tmpl=#tmpl1"&gt;&lt;/select&gt;
&lt;script type="text/html" id="tmpl1"&gt;
    &lt;option value="{{: item.id}}"&gt;text_id_{{: item.text | text}}&lt;/option&gt;
&lt;/script&gt;
</code></pre>
<p>tmpl=以’#’开头，认为是一个dom node Id</p>
<h4>4、过滤器写法：</h4> 
<pre><code>&lt;select bg-foreach="item in list | desc:'id' tmpl=#tmpl1"&gt;&lt;/select&gt;
&lt;script type="text/html" id="tmpl1"&gt;
    &lt;option value="{{: item.id}}"&gt;text_id_{{: item.text | text}}&lt;/option&gt;
&lt;/script&gt;
</code></pre>
<p>过滤器**desc**是对list先进行反序排序，再render</p>
<h4>5、模板语法</h4>
<p>请参考模板render</p>
			</div>

																						<h5 id="text_55595" class="sin_target">bg-include</h5>
<div class="sin_text">
    					<p>内容引用指令，主要用于重复使用的内容引用，引用有以下二种方式：<br>- 通过**id**引用标签定义的“内部内容”;<br>- 通过**url**引用同域的内容文件;</p>
<h4>1、通过**id**引用模板内容:</h4> 
<pre><code>&lt;div bg-include="#tmpl1"&gt;&lt;/div&gt;
&lt;script id="tmpl1" type="text/html"&gt;
  &lt;div&gt;{{: title}}&lt;/div&gt;
&lt;/script&gt;
</code></pre>
<p>如果**bg-include**内容以’#‘开头，认为是一个ID，并以tmpl = $(’#tmpl1’).html()为内容</p>
<h4>2、通过**url**引用同域的内容文件:</h4> 
<pre><code>&lt;div bg-include="include_tmpl.html"&gt;&lt;/div&gt;
</code></pre>
<p>如果**bg-include**内容不是以’#’开头，认为是一个route url，**include_tmpl.html**为引用文件远程地址</p>
<h4>3、**bg-include**如何确定引用方式？</h4> 
<ul> 
 <li>会先确定是否与变量绑定， 如果有，取得其值(可用于动态引用)</li> 
 <li>如果没，检查否以‘#’开头， 如果是，确定为dom node的ID</li> 
 <li>如果没，确定为route url远程加载</li> 
</ul>
			</div>

																						<h5 id="text_55596" class="sin_target">bg-render-include</h5>
<div class="sin_text">
    					<p>bg-render-include模板标签，支持其内容为render模板, 其它跟bg-include一样<br> </p>
<pre><code><br>&lt;div bg-render-include="include_tmpl.html"&gt;&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55597" class="sin_target">bg-if</h5>
<div class="sin_text">
    					<p><strong>bg-if</strong>主要用于界面分支显示，也可以bg-show | bg-hide来实现同一效果；但bg-if更为撤底，原因bg-if会把下级节点清除，去除没必要的绑定，以提高性能；<br> </p>
<pre><code><br>&lt;div id="testView" bg-action="action1"&gt;
    &lt;div bg-if="isOk | eq:'1'"&gt;&lt;span&gt;你选择了 "真"&lt;/span&gt;&lt;/div&gt;
    &lt;div bg-if="isOk | neq:'1'"&gt;&lt;span&gt;你选择了 "假"&lt;/span&gt;&lt;/div&gt;
    &lt;select bg-model="isOk"&gt;
        &lt;option value="1"&gt;真&lt;/option&gt;
        &lt;option value="0"&gt;假&lt;/option&gt;
    &lt;/select&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.isOk = '1';
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55598" class="sin_target">bg-render-if</h5>
<div class="sin_text">
    					<p>bg-render-if模板标签，支持其内容为render模板, 其它跟bg-if一样<br> </p>
<pre><code><br>&lt;div bg-render-if="true"&gt;
    &lt;script type="text/html"&gt;
        {{for item in list}}
            {{: item.id}}:{{: item.name}}
        {{/for}}
    &lt;/script&gt;
&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55599" class="sin_target">bg-attr</h5>
<div class="sin_text">
    					<p><strong>bg-attr</strong>直接与Dom节点属性(attr)绑定:<br> </p>
<pre><code><br>&lt;div id="testView" bg-action="action1"&gt;
    &lt;div bg-attr="{aaa:1,bbb:23, ccc:testVal}"&gt;请查看生成后的属性&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.testVal = 100;
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55600" class="sin_target">bg-style</h5>
<div class="sin_text">
    					<p>直接与Dom节点样式(style)绑定:<br> </p>
<pre><code><br>&lt;div id="Div1" bg-action="action1"&gt;
    &lt;div bg-style="{width:width, 'background-color':'red'}"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.width = 100;
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55601" class="sin_target">bg-model</h5>
<div class="sin_text">
    					<p><strong>bg-model</strong>表单控件类的模板指令，最大的作用是它预定义了需要绑定的数据的格式。这样，就可以对于既定的数据进行既定的处理</p> 
<pre><code>&lt;div id="Div1" bg-action="action1"&gt;

    &lt;div&gt;input: &lt;input type="text" bg-model="data.input" /&gt;&lt;/div&gt;

    &lt;div&gt;select: &lt;select bg-model="data.select"&gt;
            &lt;option value="1"&gt;1111&lt;/option&gt;
            &lt;option value="2"&gt;222&lt;/option&gt;
        &lt;/select&gt;
    &lt;/div&gt;

    &lt;div&gt;checkbox: &lt;input type="checkbox" value="chk" bg-model="data.checkbox" /&gt;&lt;/div&gt;

    &lt;div&gt;radio:
        &lt;input type="radio" value="rd1" name="rr" bg-model="data.radio" /&gt;
        &lt;input type="radio" value="rd2" name="rr" bg-model="data.radio" /&gt;
    &lt;/div&gt;

    &lt;div&gt;textarea: &lt;textarea bg-model="data.textarea"&gt;&lt;/textarea&gt; &lt;/div&gt;

    &lt;button bg-click="save"&gt;提交&lt;/button&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.data = {
            input: '1',
            select: '2',
            checkbox:'chk',
            radio: 'rd1',
            textarea:'text'
        };
        $view.save = function () {
            console.log($view.data);
        };
    });
&lt;/script&gt;
</code></pre>
<p>上面代码寅示**bg-model**在表单各种元素的用法</p>
			</div>

																						<h5 id="text_55602" class="sin_target">bg-text</h5>
<div class="sin_text">
    					<p>绑定Dom节点文本内容:<br> </p>
<pre><code><br>&lt;div id="Div1" bg-action="action1"&gt;
    &lt;div bg-text="text1"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.text1 = "你好";
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55603" class="sin_target">bg-html</h5>
<div class="sin_text">
    					<p>绑定Dom节点html内容, 并自动编译:<br> </p>
<pre><code><br>&lt;div id="Div1" bg-action="action1"&gt;
    &lt;div bg-html="text1"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.html1 = '&lt;span bg-text="text1"&gt;&lt;/span&gt;bingo';
        $view.text1 = "你好";
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55604" class="sin_target">bg-not-compile</h5>
<div class="sin_text">
    					<p>不编译下级提高编译速度:<br> </p>
<pre><code><br>&lt;div bg-not-compile&gt;
    下面不会编译
&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55605" class="sin_target">事件指令（event）</h5>
<div class="sin_text">
    					<p>直接与Dom节点事件(event)绑定:<br> </p>
<pre><code><br>&lt;div id="Div1" bg-action="action1"&gt;
    &lt;button bg-event="{click:clickTest}"&gt;event方式&lt;/button&gt;
    &lt;button bg-click="clickTest"&gt;事件方式1&lt;/button&gt;
    &lt;button bg-click="clickAlert('test')"&gt;事件方式2&lt;/button&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bigno.action(function ($view, $node) {
        $view.clickTest = function (e) {
            alert('click');
        };
        $view.clickAlert = function (msg) {
            alert(msg);
        };
    });
&lt;/script&gt;
</code></pre>
<p></p>
<p>如上代码事件可以有两种方式调用：一是绑定；二是直接执行；<br>支持事件有：<br> - click：click事件<br> - blur：失去焦点的时候触发<br> - dblclick：双击时触发<br> - focus：设置焦点时触发<br> - focusin：获得焦点的时候会触发这个事件<br> - focusout：失去焦点的时候会触发这个事件<br> - keydown：键盘按下时触发<br> - keypress：键盘按下时触发<br> - keyup：在按键释放时触发<br> - mousedown：鼠标在元素上点击后会触发<br> - mouseenter：当鼠标指针穿过元素时触发, 与mouseleave 事件一起使用<br> - mouseleave：当鼠标指针离开元素时触发, 与mouseenter 事件一起使用<br> - mousemove：元素上移动来触发<br> - mouseout：在鼠标离开对象时触发, 与mousemove事件一起使用<br> - mouseover：鼠标移入对象时触发<br> - mouseup：鼠标点击对象释放时触发<br> - resize：当文档窗口改变大小时触发<br> - scroll：当滚动条发生变化时触发<br> - select：当选择input,textarea内容时触发<br> - submit：fomr提交时触发</p>
			</div>

																						<h5 id="text_55606" class="sin_target">其它常用指令</h5>
<div class="sin_text">
    					<ul> 
 <li>bg-class：操作class属性</li> 
 <li>bg-show：显示</li> 
 <li>bg-hide：隐藏</li> 
 <li>bg-visibility：可见</li> 
 <li>bg-src：操作src</li> 
 <li>bg-checked：操作checked</li> 
 <li>bg-unchecked：操作checked反操作</li> 
 <li>bg-enabled：操作允许</li> 
 <li>bg-disabled：操作禁用</li> 
 <li>bg-readonly：只读</li> 
 <li>集成jQuery所有事件</li> 
</ul>
<p>以上指令除了bg-checked/bg-unchecked指令是双向绑定， 其他所有都是单向绑定</p>
			</div>

																						<h5 id="text_55703" class="sin_target">bg-loaded</h5>
<div class="sin_text">
    					<p>绑定Dom节点html内容, 并自动编译:<br> </p>
<pre><code><br>&lt;div id="Div1" bg-action="action1"&gt;
    &lt;div bg-loaded="loaded"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.loaded= function(){$(this).html('你好！')};
    });
&lt;/script&gt;
</code></pre>
<p></p>
			</div>

																						<h4 id="category_13125">自定义模板指令</h4>
																						<h5 id="text_55607" class="sin_target">指令名称定义</h5>
<div class="sin_text">
    					<p>目前我们看到的“模板”系统，只不过是框架实现的几个指令而已。这意味着，通过自定义各种指令，我们不但可以完全定义一套“模板”系统，更可以把 HTML 页面直接打造成为一种 DSL （领域特定语言）。</p>
<p>使用指令时，它的名字可以有多种形式，把指令放在什么地方也有多种选择。</p>
<p>通常，指令的定义名是形如 bgBind 这样的 “camel cased” 形式。在使用时，它的引用名可以是：</p>
<p>bg_bind<br>bg-bind<br>x-bg-bind<br>data-bg-bind<br>你可以根据你自己是否有 “HTML validator” 洁癖来选择。</p>
<p>指令可以放在多个地方，它们的作用相同：</p>
<p><span></span> 作为标签的属性<br><span></span> 作为标签类属性的值<br> 作为标签<br>这些方式可以使用指令定义中的 restrict 属性来控制。</p>
<p>可以看出，指令即可以作为标签使用，也可以作为属性使用。</p>
			</div>

																						<h5 id="text_55608" class="sin_target">指令的执行过程</h5>
<div class="sin_text">
    					<p>对指令的解析与执行过程是这样的：</p> 
<ul> 
 <li>浏览器得到 HTML 字符串内容，解析得到 DOM 结构。</li> 
 <li>bingoJS 引入，把 DOM 结构扔给 $compile 函数处理：</li> 
 <li>找出 DOM 结构中有变量占位符</li> 
 <li>匹配找出 DOM 中包含的所有指令引用</li> 
 <li>把指令关联到 DOM</li> 
 <li>关联到 DOM 的多个指令按权重排列</li> 
 <li>执行指令中的 compilePre 函数，处理编译前的DOM , 改变 DOM 结构或内容</li> 
 <li>执行指令中的 compile 函数，处理action之前指令相关准备, 定义特殊指令</li> 
 <li>执行指令中的 action 函数，收集action定义时的初始数据，这里就是我们的action</li> 
 <li>执行指令中的 link 函数，处里一般指令定义，与指令关联起来，使用$subs订阅信息</li> 
 <li>link初始化，将初始数反映到dom显示出来</li> 
 <li>发送$view.onInitData事件，运程加载初始数据；</li> 
 <li>发送$view.onReady事件，$view准备；</li> 
 <li>如果所有子孙$view都准备好，发送$view.onReadyAll</li> 
</ul>
			</div>

																						<h5 id="text_55609" class="sin_target">简单的自定义</h5>
<div class="sin_text">
    					<p>自定义一个指令可以是非常的复杂，但是其基本的调用形式，同自定义服务大概是相同的：<br> </p>
<pre><code><br><br>bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, $node) {
  
        var _set = function (val) {
            $node.text(bingo.toStr(val));
        };

        //订阅执行结果， 如果执行结果改变时，同步数据
        $attr.$subsResults(function (newValue) {
            _set(newValue);
        });

        //根据执行结果初始结果
        $attr.$initResults(function (value) {
            _set(value);
        });

    }];
});

</code></pre>
<p></p>
<p>上面代码， 是定义模板指令**bg-text**的过程；在简单定义里，我们返回一个function或一个注入格式数组（防止压缩JS失效）就可以了；在整个定义过程中，主要使用**$attr**提供的接口（详细说明可能参考$attr说明）**$initResults**做初始化和**$subsResults**订阅信息做同步数据，并且用$node将数据输出来dom，这样我们就可以简单完成**bg-text**的定义；接下来就可以这样使用了：</p> 
<pre><code>&lt;div bg-action="action1"&gt;
   &lt;span bg-text="title"&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;script&gt;
  var action1 = bingo.action(function($view){
     $view.title = "标题"; //初始title

     setTimeout(function(){
       $view.title = '新标题';//修改title
       $view.$update();//刷新$view（同步数据）
     }, 1000);
  });
&lt;/script&gt;
</code></pre>
<p>你还可以到这里查看更多<a href="http://git.oschina.net/bingoJS/bingoJS/tree/master/js/bingo/mv/command?dir=1&amp;filepath=js%2Fbingo%2Fmv%2Fcommand&amp;oid=2e2fe2e0c4595d6197b7d9722404360eef7c7112&amp;sha=4d87c7b5f8b37ce1a83e8a500e35ef4ce664fe0a" rel="nofollow">定义模板指令</a></p>
			</div>

																						<h5 id="text_55610" class="sin_target">完整的自定义</h5>
<div class="sin_text">
    					<p>在简单的定义中，其实是使用了完整定义的一个属性**link**，请看下面的bg-action定义（<a href="http://git.oschina.net/bingoJS/bingoJS/blob/master/js/bingo/mv/command/action.js?dir=0&amp;filepath=js%2Fbingo%2Fmv%2Fcommand%2Faction.js&amp;oid=c93855ff8978e56a5e0763ef3d6f534cd25d0289&amp;sha=4d87c7b5f8b37ce1a83e8a500e35ef4ce664fe0a" rel="nofollow">点击这里看详细定义</a>）：</p> 
<pre><code>bingo.command('bg-action', function () {

    return {
        //优先级, 越大越前, 默认50
        priority: 1000,
        //模板
        tmpl: '',
        //外部模板
        tmplUrl: '',
        //是否替换节点, 默认为false
        replace: false,
        //是否indclude, 默认为false, 模板内容要包函bg-include
        include: false,
        //是否新view, 默认为false
        view: true,
        //是否编译子节点, 默认为true
        compileChild: false,
        //编译前, 没有$viewnode和$attr注入, 但可以用不依懒$domnode和$attr的所有注入, 如$view/node/$node/$ajax...
        //如果view == true , 注入的view属于父层, 原因是新view还没解释出来, 还处于分析
        compilePre: null,
        //action
        action: null,
        //link
        link: null,
        //编译, (compilePre编译前--&gt;compile编译--&gt;action初始数据--&gt;link连接command)
        compile: ['$view', '$compile', '$node', '$attr', function ($view, $compile, $node, $attr) {
           ...
           $compile().fromNode($node[0].childNodes).compile();
           ...
        }]
    };
});
</code></pre>
<p>上面代码是完整定义模板指令所有参数，这时我们返回一个配置JSON Object</p>
<h4>1、tmpl</h4>
<p>是指定义指令的模板，如定义**bg-demotmpl**使用**tmpl**属性：<br> </p>
<pre><code><br>bingo.command('bg-demotmpl', function () {
    return {
        //模板
        tmpl: '&lt;span&gt;{{: title}}&lt;/span&gt;',
        //link
        link:['$view', function ($view) {
           ...
        }]
    };
});
</code></pre>
<br>使用指令如下：
<br> 
<pre><code><br>&lt;div bg-demotmpl&gt;&lt;/div&gt;
&lt;script&gt;
  var title = '标题';
&lt;/script&gt;
</code></pre>
<br>最结果会这样：
<br> 
<pre><code><br>&lt;div bg-demotmpl&gt;
  &lt;span&gt;标题&lt;/span&gt;
&lt;/div&gt;
</code></pre>
<br>所以tmpl属性内容是一个我们要指定的模板，最终会生成指令所在dom node的innerHtml;
<p></p>
<h4>2、tmplUrl</h4>
<p>这个属性跟**tmpl**实现效果是一样的，只不过这个提令是从远程url（route url）加载模板而已：<br> </p>
<pre><code><br> return {
   tmplUrl:'view/tmpl/demotmpl.html'
 }
</code></pre>
<p></p>
<h4>3、replace</h4>
<p>是指是否代替原来dom node，必须指定**tmpl**或**tmplUrl**属性：<br> </p>
<pre><code><br>bingo.command('bg-demotmpl', function () {
    return {
        //模板
        tmpl: '&lt;span&gt;{{: title}}&lt;/span&gt;',
        //是否替换节点, 默认为false
        replace: true,
        //link
        link:['$view', function ($view) {
           ...
        }]
    };
});
</code></pre>
<br>使用指令如下：
<br> 
<pre><code><br>&lt;div bg-demotmpl&gt;&lt;/div&gt;
&lt;script&gt;
  var title = '标题';
&lt;/script&gt;
</code></pre>
<br>最结果会这样：
<br> 
<pre><code><br>&lt;span&gt;标题&lt;/span&gt;
</code></pre>
<br>在这里，我们看到跟只有**tmpl**属性不一样，它指原来的dom node完全替换掉了；
<p></p>
<h4>4、include</h4>
<p>是指是否include原来dom node，必须指定**tmpl**或**tmplUrl**属性：<br> </p>
<pre><code><br>bingo.command('bg-demotmpl', function () {
    return {
        //模板
        tmpl: '&lt;span&gt;{{: title}}&lt;span bg-include&gt;&lt;span&gt;&lt;/span&gt;',
        //是否替换节点, 默认为false
        replace: true,
        //link
        link:['$view', function ($view) {
           ...
        }]
    };
});
</code></pre>
<br>使用指令如下：
<br> 
<pre><code><br>&lt;div bg-demotmpl&gt;你好&lt;/div&gt;
&lt;script&gt;
  var title = '标题';
&lt;/script&gt;
</code></pre>
<br>最结果会这样：
<br> 
<pre><code><br>&lt;span&gt;标题&lt;span bg-include&gt;&lt;div bg-demotmpl&gt;你好&lt;/div&gt;&lt;span&gt;&lt;/span&gt;
</code></pre>
<br>在这里，我们看到跟只有**tmpl**属性不一样，它指原来的dom node完全include到**bg-include**标签里了；
<p></p>
<h4>5、compilePre | compile | action | link</h4>
<p>这四个属性定义方式是一样， 可以是一个function(inject…)或注入格式的数组[$view, function(inject…)];</p>
<p>它们在编译过程，代表不同的时机和顺序而已：<br>1. <strong>compilePre</strong>，编译前，这里还没有对dom node解释，这时可以对原始dom node处理，注意是如果属性view为true, 这里注入的$view是父层的view，这样我们还可以做一些与父层view做关联处理；<br>2. <strong>compile</strong>，编译后，这样只要做动态编译的情事，如bg-action是编译子级dom node的，这里可以处理一些事情后再动态编译下级dom node<br>3. <strong>action</strong>，初始数据，其它是我们用bingo.action定义的action同一级别，所以这里是处理action业务的<br>4. <strong>link</strong>，连接**command**，对指令的初始和订阅等处理等</p>
<p>最后发送**$view.onReady**事件</p>
			</div>

																												<h4 id="text_55666" class="sin_target">数据绑定与模板</h4>
<div class="sin_text">
    					<p>在**bingoJS**里， 数据绑定与模板是主功能之一； 如果没有它，就没有可以面向业务编程了。通常模板是可以html dom或html 文本, 然后通过指令与数据绑定，从而做view层和action分离出来。</p>
<h4>1、数据-&gt;模板</h4>
<p>数据到表现的绑定，主要是使用模板标记直接完成的：<br> </p>
<pre><code><br>&lt;p bg-text="hello"&gt;&lt;/p&gt;
&lt;p&gt;tag: {{hello}}&lt;/p&gt;
</code></pre>
<br>使用指令或{{ }}标签，就可以直接引用，并绑定一个作用域内的变量。在实现上， 
<strong>bg</strong> 自动通过 $subscribe（简写$subs）观察变量 。效果就是，不管因为什么，如果作用域的变量发生了改变，我们随时可以让相应的页面表现也随之改变。我们可以看下面的例子：
<br> 
<pre><code><br>&lt;div id="testView" bg-action="action1" bg-text="aaa"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1= bingo.action(function ($view) {
        $view.aaa = '10'
    });
&lt;/script&gt;
</code></pre>
<br>上面的例子在页面载入之后，我们可以在页面上看到 10 。这时，我们可以打开浏览器控制台，输入：
<br> 
<pre><code><br>var view = bingo.getView('#testView');
view.aaa = 99;
view.$update();
</code></pre>
<br>上面的代码执行之后，就可以看到页面变化了。对于使用 
<strong>bg</strong> 进行的事件绑定，在处理函数中就不需要去关心 \$upate() 的调用了，因为 
<strong>bg</strong> 会自己处理。
<p></p>
<h4>2、模板-&gt;数据</h4>
<p>模板到数据的绑定，主要是通过 <strong>bg-model</strong> 来完成的：<br> </p>
<pre><code><br>&lt;input id="testView" bg-action="action1" bg-model="aaa" /&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view) {
        $view.aaa = '10'
    });
&lt;/script&gt;
</code></pre>
<br>这时修改 input 中的值，我们可以打开浏览器控制台，输入：
<br> 
<pre><code><br>bingo.view('#testView').aaa;
</code></pre>
<br>查看，发现变量 aaa 的值已经更改了。
<p></p>
<p>实际上， <strong>bg-model</strong> 是把两个方向的绑定都做了。它不光显示出变量的值，也把显示上的数值变化反映给了变量。这个在实现上就简单多了，只是绑定 <strong>change</strong> 事件，然后做一些赋值操作即可。</p>
<h4>3、模板-&gt;数据-模板</h4>
<p>现在要考虑的是一种在现实中很普遍的一个需求。比如就是我们可以输入数值，来控制一个矩形的长度:<br> - 长度数值保存在变量中<br> - 变量显示于某个 input 中<br> - 变量的值即是矩形的长度<br> - input 中的值变化时，变量也要变化<br> - input 中的值变化时，矩形的长度也要变化</p> 
<pre><code>&lt;div id="testView" bg-action="action1"&gt;
    &lt;input bg-model="width" /&gt;
    width: {{width}}
    &lt;div style="width: 100px; height: 10px; background-color: red"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view, $node) {
        $view.width = 100;
        $view.$subs('width', function () {
            $node.find('div').width($view.width);
        });
    });
&lt;/script&gt;
</code></pre>
<p>上面例子中， 变量width与input绑定， 并使用**$subs**来观察width的值， 当我们在input框中输入数量时 ，变量width也同时改变，这里**$subs**观察到width的改变，并通过**$node**(jQuery对象)，操作div的宽度。</p>
			</div>

																						<h3 id="category_13133">过滤器filter</h3>
																						<h4 id="text_55692" class="sin_target">概述</h4>
<div class="sin_text">
    					<p>过滤器，是用于简单对数据的格式化，或者筛选的函数。它们可以直接在模板中通过一种语法使用。对于常用功能来说，是很方便的一种机制。</p>
<p>多个过滤器之间可以直接连续使用：<br> </p>
<pre><code><br>&lt;div bg-show="datas.text | len | gt:0"&gt;{{: datas.text}}&lt;/div&gt;
</code></pre>
<br>上面代码，如果**datas.text**长度大于0显示内容
<p></p>
			</div>

																						<h4 id="text_55693" class="sin_target">自带filter</h4>
<div class="sin_text">
    					<h4>1.等于 eq</h4>
<p><strong>eq</strong>是用于比较数据是否相等某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | eq:23"&gt;23&lt;/div&gt;
</code></pre>
<p></p>
<h4>2.不等于 neq</h4>
<p><strong>eq</strong>是用于比较数据是否不相等某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | neq:23"&gt;24&lt;/div&gt;
</code></pre>
<p></p>
<h4>3.大于 gt</h4>
<p><strong>gt</strong>是用于比较数据是否大于某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | gt:23"&gt;24&lt;/div&gt;
</code></pre>
<p></p>
<h4>4.大于等于 gte</h4>
<p><strong>gte</strong>是用于比较数据是否大于等于某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | gte:23"&gt;24&lt;/div&gt;
</code></pre>
<p></p>
<h4>5.小于 lt</h4>
<p><strong>lt</strong>是用于比较数据是否小于某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | lt:23"&gt;22&lt;/div&gt;
</code></pre>
<p></p>
<h4>6.小于等于 lte</h4>
<p><strong>lte</strong>是用于比较数据是否大于等于某个数据，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.age | lte:23"&gt;22&lt;/div&gt;
</code></pre>
<p></p>
<h4>7.取反 not</h4>
<p><strong>not</strong>是用于数据取反，返回true/false<br> </p>
<pre><code><br>&lt;div bg-show="user.isAdmin | not"&gt;user&lt;/div&gt;
</code></pre>
<p></p>
<h4>8.获取长度 len</h4>
<p><strong>len</strong>是用于获取数据长度<br> </p>
<pre><code><br>&lt;div bg-show="user.name | len"&gt;8&lt;/div&gt;
</code></pre>
<p></p>
<h4>9.返回文本 text</h4>
<p><strong>text</strong>是用于数据htmlEncode编码，显示为文本<br> </p>
<pre><code><br>&lt;div bg-html="user.name | text"&gt;&lt;/div&gt;
</code></pre>
<p></p>
<h4>10.返回html html</h4>
<p><strong>html</strong>是用于数据htmlDecode解编码，显示为html<br> </p>
<pre><code><br>&lt;div bg-html="user.name | html"&gt;&lt;/div&gt;
</code></pre>
<p></p>
<h4>11.多元操作 sw</h4>
<p><strong>sw</strong>是用于数据多元操作, 如 isOk ? true : false<br> </p>
<pre><code><br>&lt;div bg-class="user.name | sw:['小明', 'red', '小李', 'blue', 'gray']"&gt;&lt;/div&gt;
</code></pre>
<br>上面代码意思，user.name == ‘小明’ ? ‘red’ : (user.name == ‘小李’ ? ‘blue’ : ‘gray’)
<p></p>
<p><strong>sw</strong>还可以用于tab切换<br> </p>
<pre><code><br>&lt;ul&gt;
 &lt;li bg-class="tabIndex | sw:[0, 'blue', '']" bg-click="tabIndex(0)"&gt;页面1&lt;/li&gt;
 &lt;li bg-class="tabIndex | sw:[1, 'blue', '']" bg-click="tabIndex(1)"&gt;页面2&lt;/li&gt;
&lt;ul&gt;
</code></pre>
<p></p>
<h4>12.获取数组指定部分数据 take</h4>
<p><strong>take</strong>获取数组指定部分数据, take:[开始位置,获取数量（可选，默认所有）]<br> </p>
<pre><code><br>&lt;div bg-render="[1,2,3] | take:[1,2]"&gt;&lt;/div&gt;
</code></pre>
<p></p>
<h4>13.升序排序 asc</h4>
<p><strong>asc</strong>对数据升序排序, asc:‘属性名称，可选’<br> </p>
<pre><code><br>&lt;div bg-render="[1,2,3] | asc"&gt;&lt;/div&gt;
</code></pre>
<p></p>
<h4>13.升序排序 desc</h4>
<p><strong>desc</strong>对数据升序排序, desc:‘属性名称，可选’<br> </p>
<pre><code><br>&lt;div bg-render="[1,2,3] | desc"&gt;&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55694" class="sin_target">自定义filter</h4>
<div class="sin_text">
    					<p>定义filter是很简单的，我只需返回一个特定格式function即可：<br> </p>
<pre><code><br>bingo.filter('eq', function () {
    return function (value, para) {
        return value == para;
    };
});
</code></pre>
<br>框架会向function进入要过滤的值和参数（如果有参数），然我们要做的是返回过滤结果;
<p></p>
<p>接下来就可以这样使用它了：<br> </p>
<pre><code><br>&lt;div bg-show="user.isAdmin | eq:1"&gt;管理员&lt;/div&gt;
</code></pre>
<br>上面代码，我们可以这样理解，user.isAdmin为value, 1为para, 结果是 user.isAdmin == 1
<p></p>
<p><code>注意，过滤器不能直接使用多个的参数的，如果要多个参数只能用数组方式：</code><br> </p>
<pre><code><br>&lt;div bg-text="user.name | subs:1, 2"&gt;&lt;/div&gt;
</code></pre>
<br>这样使用就出现错误的，只能改用下面方式使用：
<br> 
<pre><code><br>&lt;div bg-text="user.name | subs:[1, 2]"&gt;&lt;/div&gt;
</code></pre>
<br>我们只能用数组方式，传入多个参数，看看它的定义:
<br> 
<pre><code><br>bingo.filter('subs', function () {
    return function (value, para) {
        return value  ? '' : value.subs(para[0], para[1]);
    };
});
</code></pre>
<p></p>
			</div>

																						<h3 id="category_13134">模板render</h3>
																						<h4 id="text_55695" class="sin_target">概述</h4>
<div class="sin_text">
    					<p>render是一个文本模板解释引擎，如jsRender之类的，在框架它已经完美结合在html绑定模板里去了，具体详情可能参考指令**bg-render**。为什么有了html绑定模板，还要render模板呢？原因html绑定模板一般是先解释成dom node，然后遍历所有dom node进行编译，然而这过程会产生大量不需要的dom node，这样会影响编译性能；如果我们先render本文本生成比较干净的html绑定模板，这样就能节省很多计算资源；</p>
<p><strong>tmpl</strong>：render 模板</p> 
<pre><code>bingo.action('list', function($view, $render){
  //render模板
  var tmpl = '&lt;div&gt;{{: item.name}}&lt;/div&gt;';
  //数据
  var list =[{name:'小明'}, {name:'小李'}];
  //创建render, 并解释输出到html
  var rd = $render(tmpl);
  var html = rd.render(list);
  //解释结果
  html === '&lt;div&gt;小明&lt;/div&gt;&lt;div&gt;小明&lt;/div&gt;'

});
</code></pre>
<h3>模板语法：</h3>
<p>—<br><strong>$render所支持的模板语法：</strong><br>1. 支持**输出**语句, 如: {{: item.name}} {{: document.body.childNodes[0].nodeName}}<br>2. 支持**if**语句, 如: {{if item.isLogin} 已登录 {{else}} 未登录 {{/if}}<br>3. 支持**for**语句, 如: {{for item in list}} {{: item_index}}| {{: item.id}}|{{: item_count}}|{{: item_first}}|{{: item_last}} {{/for}}<br>4. 支持**for /**语句, 如: {{for item in list tmpl=#idAAA /}}<br>5. 支持**tmpl**(注释)语句, 如 {{tmpl}} {{: item.text}} {{tmpl}}<br>6. 支持**过滤器**, 如: {{: item.name | text}}, 请参考过滤器<br>7. 支持**header**语句, 如: {{header}} 这里是头部 {{/header}}<br>8. 支持**footer**语句, 如: {{footer}} 这里是底部 {{/footer}}<br>9. 支持**empty**语句, 如: {{empty}} 当数据源数组为[], 长度为0 {{/empty}}<br>10. 支持**loading**语句, 如: {{loading}} 当数据源为null时 {{/loading}}</p>
<h4>模板标签</h4>
<p><strong>{{指令 js表达}}</strong>, 所有模板标签都要用**{{}}**双大括号包起来，里面是**模板指令**+**JS表达式**</p>
<p><code>注意 js表达作用域，查找变量最优先查找数据项，再查询$view，最后到window</code></p>
			</div>

																<h4 id="category_13123">render语法</h4>
																						<h5 id="text_55582" class="sin_target">输出语句</h5>
<div class="sin_text">
    					<p>语法：**{{:** js表达式**}}**<br> </p>
<pre><code><br>  //可以数据项属性
  var tmpl = '&lt;div&gt;{{: item.name}}&lt;/div&gt;';

  //可以任何JS表达，并输出计算结果
  tmpl = '&lt;div&gt;{{: 1+2}}&lt;/div&gt;';
  tmpl = '&lt;div&gt;{{: new Date().toString()}}&lt;/div&gt;';
  tmpl = '&lt;div&gt;{{: JSON.stringify({bbb:"111"}) }}&lt;/div&gt;';
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55583" class="sin_target">if</h5>
<div class="sin_text">
    					<h4>条件语句if</h4>
<p>语法：**{{if** js表达式**}}** 内容 <strong>{{else</strong> js表达式**}}**内容 <strong>{{else}}</strong> 内容 <strong>{{/if}}</strong><br> </p>
<pre><code><br>  //使用if语句
  var tmpl = '{{if item.name == '小明'}}&lt;div&gt;{{: item.name}}&lt;/div&gt;{{/if}}';

  //多层if
  tmpl = '{{if item.name == '小明'}}{{if item.age &lt; 23}}&lt;div&gt;{{: item.name}}&lt;/div&gt;{{/if}}{{/if}}';

  //if else
  tmpl = '{{if item.admin}} admin {{else item.man}} man {{else}} work {{/if}}'
</code></pre>
<p></p>
<p>与bg-render结合：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;
    &lt;select bg-render="item in list"&gt;
        {{if item.id == 1}}
        &lt;option value="{{: item.id}}"&gt;{{: item.name | text}}&lt;/option&gt;
        {{/if}}
    &lt;/select&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view) {
        $view.list = [{
            id: 1,
            name: '选项1'
        }, {
            id: 2,
            name: '选项2'
        }];
    });
&lt;/script&gt;
</code></pre>
<br>上面主要是实现下拉框select的数据源填充，过程使用了if item.id == 1，所以下拉框只会出现“选项1”一个下拉选项
<p></p>
			</div>

																						<h5 id="text_55584" class="sin_target">for</h5>
<div class="sin_text">
    					<h4>循环语句for</h4>
<p>语法：**{{for** item in list**}}** 内容 <strong>{{/for}}</strong><br> </p>
<pre><code><br>  //使用for语句
  var tmpl = '{{for itemPack in item.packs}} {{: itemPack.name}} {{/for}}';
  
  var list = [{id:1, packs:[{name:'小包'},{name:'大包'}]}];
  $render(tmpl).render(list);
</code></pre>
<p></p>
<p>与bg-render结合，实现下拉框数据源填充：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;
    &lt;select bg-render="item in list"&gt;
        &lt;option value="{{: item.id}}"&gt;{{: item.name | text}}&lt;/option&gt;
    &lt;/select&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view) {
        $view.list = [{
            id: 1,
            name: '选项1'
        }, {
            id: 2,
            name: '选项2'
        }];
    });
&lt;/script&gt;
</code></pre>
<br>在上面代码中，**bg-render**代表一个render模板，模板内容就是相关dom node的html，整体就好像我们执行下面代码:
<br> 
<pre><code><br> var tmpl = $node.find('bg-render').html();
 var html = $render(tmpl).render(list, 'item');
 $node.find('bg-render').html(html);

</code></pre>
<p></p>
<p>多层for问题：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;
    &lt;ul bg-render="item in list"&gt;
        &lt;script type="text/html"&gt;
        &lt;li&gt;
            &lt;a href="###"&gt;{{: item.name | text}}&lt;/a&gt;
            &lt;ul&gt;
                {{for childItem in item.children}}
                &lt;li&gt;
                    &lt;a href="###"&gt;{{: childItem.name | text}}&lt;/a&gt;
                &lt;/li&gt;
                {{/for}}
            &lt;/ul&gt;
        &lt;/li&gt;
        &lt;/script&gt;
    &lt;/ul&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var action1 = bingo.action(function ($view) {
        $view.list = [{
            id: 1,
            name: '主导航1',
            children: [{
                id: 11,
                name: '子导航1'
            }, {
                id: 12,
                name: '子导航2'
            }]
        }, {
            id: 2,
            name: '主导航2'
        }];
    });
&lt;/script&gt;
</code></pre>
<br>上面代码我们实现一个两层导航，这里主要想说明多层**for**取值问题；如代码**item**和**childItem**，它们分别表示**主导航项**和**子导航项**，就像我们写for JS代码一样**item**作用范围是整个render模板，**childItem**作用范围只在{{for..}} {{/for}}之间
<p></p>
<h4>for内置变量</h4>
<p><strong>格式</strong>: 数据项名称_变量名称</p>
<p>下面如果数据项名称是’<strong>item</strong>’：<br>- item_index：索引<br>- item_count：数量<br>- item_first：是否第一个<br>- item_last：是否最后一个<br>- item_odd：是否单<br>- item_even：是否双 </p>
<p><code>注意上面item是一个数据项名称，要根据情况改变，如下面代码的item_index和childItem_index：</code><br> </p>
<pre><code><br>&lt;ul bg-render="item in list"&gt;
    &lt;script type="text/html"&gt;
    &lt;li&gt;
        {{: item_index}} / {{: item_count}}
        &lt;ul&gt;
            {{for childItem in item.children}}
            &lt;li&gt;
                {{: childItem_index}} / {{: childItem_count}}
            &lt;/li&gt;
            {{/for}}
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;/script&gt;
&lt;/ul&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55585" class="sin_target">for /</h5>
<div class="sin_text">
    					<h4>循环语句for /</h4>
<p>语法：**{{for** item in list tmpl=#idAAA <strong>/}}</strong></p>
<p>这个语句主要用于引用外部模板如：<br> </p>
<pre><code><br>&lt;div bg-render="item in list"&gt;
   {{for childItem in item.children tmpl=#idAAA /}}
&lt;/div&gt;
&lt;script id="idAAA" type="text/html"&gt;
  &lt;span&gt;{{: childItem.name}}&lt;/span&gt;
&lt;/script&gt;
</code></pre>
<br>如果代码所说，引用了Id为idAAA的script节点里的html为模板内容来进行render;
<p></p>
<p><code>注意</code>：tmpl=#idAAA引用有两种来源方式，如果以“#”开头表示以ID查询dom node为读取模板内容，如果不是以“#”开头代表为一个route url远程加载模板，如：<br> </p>
<pre><code><br>&lt;div bg-render="item in list"&gt;
   {{for childItem in item.children tmpl=view/demo/user/info /}}
&lt;/div&gt;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55586" class="sin_target">tmpl</h5>
<div class="sin_text">
    					<h4>注释语句 tmpl</h4>
<p>语法：**{{tmpl}}** 内容 <strong>{{/tmpl}}</strong></p>
<p>tmpl语句里面的内容将不会给解释，而是直接输出:<br> </p>
<pre><code><br>  //使用for语句
  var tmpl = '{{tmpl}} {{: item.name}} {{/tmpl}}';
  
  var list = [{name:'小包'},{name:'大包'}];
  var html = $render(tmpl).render(list);
  //结果
  html === ' {{: item.name}} '; // {{: item.name}} 没有给解释
</code></pre>
<p></p>
<p>tmpl主要用于多重模板的情况， 如模板的模板</p>
<p>语法：**{{tmpl text/html}}** 内容 <strong>{{/tmpl}}</strong></p>
<p>tmpl语句里面的内容将不会给解释，而是直接输出:<br> </p>
<pre><code><br>  //使用for语句
  var tmpl = '{{tmpl text/html}} {{: item.name}} {{/tmpl}}';
  
  var list = [{name:'小包'},{name:'大包'}];
  var html = $render(tmpl).render(list);
  //结果
  html === ' &lt;script type=" text/html"&gt;{{: item.name}} &lt;/script&gt;'; // {{: item.name}} 没有给解释并使用script包起来
</code></pre>
<p></p>
<p>定义一个内联模板:<br>语法：**{{tmpl #id001}}** 内容 <strong>{{/tmpl}}</strong></p>
<p>tmpl语句里面的内容将不会给解释，而是直接输出:<br> </p>
<pre><code><br>  //使用for语句
  var tmpl = '{{tmpl #id001}}test {{/tmpl}}{{for item in list tmpl=#id001 /}}';
  //#id001为一个内联模板，可以使用for语法应用起来
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55587" class="sin_target">循环外部</h5>
<div class="sin_text">
    					<p>一般普通语句都针对循环内部有作用，而下面几个语句要在循环外部运行：<br>1. <strong>header</strong>语句, 如: {{header}} 这里是头部 {{/header}}<br>2. <strong>footer</strong>语句, 如: {{footer}} 这里是底部 {{/footer}}<br>3. <strong>empty</strong>语句, 如: {{empty}} 当数据源数组为[], 长度为0 {{/empty}}<br>4. <strong>loading</strong>语句, 如: {{loading}} 当数据源为null时 {{/loading}}</p> 
<pre><code>&lt;div bg-render="item in list"&gt;
 {{header}} 这里是头部 {{/header}}
 {{empty}} 当数据源数组为[], 长度为0， 暂无数据。 {{/empty}}
 {{loading}} 当数据源为null时, 加载中。。。 {{/loading}}
 
 &lt;span&gt;姓名：{{: item.name}}&lt;/span&gt;

 {{footer}} 这里是底部 {{/footer}}
&lt;/div&gt;
</code></pre>
			</div>

																						<h5 id="text_55588" class="sin_target">内置变量</h5>
<div class="sin_text">
    					<ol> 
 <li><strong>$parent</strong>变量, 返回上级数据, 如: {{: $parent.item.name}}</li> 
 <li><strong>$index</strong>变量, 返回当前索引, 如: {{: $index}}</li> 
 <li><strong>$count</strong>变量, 返回当前索引, 如: {{: $count}}</li> 
 <li><strong>$last</strong>变量, 是否第一个记录, 如: {{: $last}}</li> 
 <li><strong>$first</strong>变量, 是否最后一个记录, 如: {{: $first}}</li> 
 <li><strong>$odd</strong>变量, 是否单数记录, 如: {{: $odd}}</li> 
 <li><strong>$even</strong>变量, 是否双数记录, 如: {{: $even}}</li> 
</ol> 
<pre><code>&lt;script type="text/html"&gt;
  {{for item in list}}
    {{$index}}/{{$count}}: {{: item.name}}&lt;br /&gt;
  {{/for}}
&lt;/script&gt;

</code></pre>
<h4>具体化内置变量: 格式:varname_var, 如, $index可以用item_index, 看下面代码</h4> 
<pre><code>&lt;script type="text/html"&gt;
  {{for item in list}}
    {{$index}}/{{$count}}: {{: item.name}}&lt;br /&gt;
    {{item_index}}/{{item_count}}: {{: item.name}}&lt;br /&gt;
  {{/for}}
&lt;/script&gt;

</code></pre>
<p>在例子中，$index和item_index是相等的，这种变量更合适用于多层for，如：</p> 
<pre><code>&lt;script type="text/html"&gt;
  {{for item in list}}
    {{item_index}}/{{item_count}}: {{: item.name}}&lt;br /&gt;
    {{for childItem in list}}
       {{item_index}}:&lt;br /&gt;
       {{childItem_index}}/{{childItem_count}}: {{: childItem.name}}&lt;br /&gt;
    {{/for}}
  {{/for}}
&lt;/script&gt;

</code></pre>
			</div>

																												<h3 id="category_13136">注入inject</h3>
																						<h4 id="text_55698" class="sin_target">什么是注入</h4>
<div class="sin_text">
    					<p>前面例子中使用到的**$view**、**$var**之类的参数都是注入进入的，那什么是注入呢？可以简单理解为定义一个经常要用到的方法、对象、实体，在要使用时写成参数就能使用，表面好像跟普通定义方法、对象、实体，但一些场景只有注入方式才能很好的解决；比如定义某些方法都要传入**$view**，如果不用注入我们每次使用时收集**$view**（如果找不到还要想办法传送才能收集）。</p>
<p>而本框架的**service**、**action**、**command**、**filter**、**render**都支持注入，例如下面向**action**注入**$view**和**$var**<br> </p>
<pre><code><br>//定义action1
var action1 = bingo.action(function ($view, $var) {
    $view.title = $var('1111');
});
</code></pre>
<br>在注入的参数中也可以任意顺序，如下面代码，我们把**$view**和**$var**顺序改变了，但效果还是一样的
<br> 
<pre><code><br>var action1 = bingo.action(function ($var, $view) {
    $view.title = $var('1111');
});
</code></pre>
<br>当然我们也可以随意增加或减少注入参数，下面例子增加**$node**，减少了**$var**：
<br> 
<pre><code><br>var action1 = bingo.action(function ($view, $node) {
    $node.addClass('active');
    $view.title = '1111';
});
</code></pre>
<br>由此说明，在支持注入的地方，您想使用什么，只要在传入参数里写入相应的注入名称就可以实现注入了。
<p></p>
<p>另外为了解决JS压缩问题，可以使用下面写法：<br>var action1 = bingo.action([‘$view’, ‘$node’, function (v, n) {<br> n.addClass(‘active’);<br> v.title = ‘1111’;<br>});<br>原因JS压缩后，会在参数名称改变了。</p>
			</div>

																						<h4 id="text_55699" class="sin_target">定义factory</h4>
<div class="sin_text">
    					<p>上面的**$var**是如何定义的呢？我们来看下面的定义代码：<br> </p>
<pre><code><br>bingo.factory('$var', ['$view', function ($view) {
    return function (p, owner) {
        return bingo.variable(p, owner, $view);
    };
}]);
</code></pre>
<br>可以看见定义注入，是非常简单，上面的**$var**也就是对**bingo.variable**进行二次封装而已，但它帮我们做了收集**$view**参数，这样我们在订阅时只在$view范围内。
<p></p>
<p>其实定义还可简化如下：<br> </p>
<pre><code><br>bingo.factory('$var', function ($view) {
    return function (p, owner) {
        return bingo.variable(p, owner, $view);
    };
});
</code></pre>
<br>但这种方法对js压缩时会产生破坏
<p></p>
			</div>

																<h4 id="category_13132">框架自带注入</h4>
																						<h5 id="text_55667" class="sin_target">$veiw</h5>
<div class="sin_text">
    					<p><strong>$view</strong>由框架编译时自动注入，代表视图，在写**action**业务时可以向它定义变量实现绑定；总的来说前端任务就是对视图开发，所以框架是以**$view**为单位生命周期，如果相相应的**dom node**给删除了，**$view**会被销毁：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;&lt;/div&gt;
&lt;script&gt;
var action1 = bingo.action(function($view){

  $view.onReady(function(){
    //$view.$getNode()为div jquery对象
    //这里删除了div, 同时$view也会给销毁掉
    $view.$getNode().remove();
  });

  $view.onDispose(function(){
    console.log('$view 销毁!');
  });
});
&lt;/script&gt;
</code></pre>
<br>所以在定义注入时可以根据**$view**来确定生命周期；而我们要销毁一个**$view**只要用**jquery**删除相关联的**node**就可以了。
<p></p>
<p>另外，在编译时$view会生成下面内部结构：</p>
<p><img src="https://static.oschina.net/uploads/img/201505/21092753_GNrb.png" alt="$view内部结构" title="$view内部结构"></p>
<p>在以后定义指令(command)时，要大概了解的。</p>
<h3>属性与方法：</h3> 
<hr>
<h4>$parentView</h4>
<p>$parentView()</p>
<p>获取父$view<br> </p>
<pre><code><br>var parent = $view.$pagentView()
</code></pre>
<p></p>
<h4>$children</h4>
<p>获取子$view, 返回数组<br> </p>
<pre><code><br>var childs = $view.$children, item = null;
for (var i = 0, len = childe.length; i&lt;len; i++)
   item = childs[i];
</code></pre>
<p></p>
<h4>$viewnode</h4>
<p>$viewnode()</p>
<p>获取$view与在的$viewnode，$view必会有一个$viewnode，具体请参考$viewnode<br> </p>
<pre><code><br>var viewnode = $view.$viewnode();
var attr = viewnode.$getAttr('bg-action');
</code></pre>
<p></p>
<h4>$getNode</h4>
<p>$getNode([jqSeleor])</p>
<p>获取与$view相关联的dom node jQuery对象：<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;script&gt;
  var action1 = bingo.action(function($view){
    //获取div
    var jDiv = $view.$getNode();
    jDiv.addClass('actvie');

    //获取span
    var jSpan = $view.$getNode('span');
    //这个等于
    var jSpan1 = $view.$getNode().find('span')
    
  });
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$node</h4>
<p>$node()</p>
<p>获取与$view相关联的dom node对象，即等于$view.$getNode()[0]<br> </p>
<pre><code><br>var node = $view.$node();
var actionVal = $(node).attr('bg-action');
</code></pre>
<p></p>
<h4>$getViewnode</h4>
<p>$getViewnode(node)</p>
<p>获取node所属于的$viewnode，即node可以是$viewnode所对应的node及子孙node<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;script&gt;
  var action1 = bingo.action(function($view){
    var jDiv = $view.$getNode();
    var jSpan = $view.$getNode('span');
    
    var viewnode = $view.$getViewnode(jDiv[0]);
    var viewnode1 = $view.$getViewnode(jSpan[0]);
    //viewnode和viewnode1是同一个
    //原因它们都同属于一个$viewnode(bg-action)
  });
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$setModule</h4>
<p>$setModule(module)</p>
<p>设置$view所属的module，一般用于定义指令</p>
<h4>$getModule</h4>
<p>$getModule()</p>
<p>获取$view所属的module</p>
<h4>$addAction</h4>
<p>$addAction(actionFn)</p>
<p>添加$view所关联的action, 可以多个action，一般用于定义指令，如下面指令bg-acton定义代码片段:<br> </p>
<pre><code><br>var routeContext = $routeContext(url);
var actionContext = routeContext.actionContext();

if (actionContext.action) {
    //如果acion不为空, 即已经定义action

    //设置module
    $view.$setModule(actionContext.module);
    //添加action
    $view.$addAction(actionContext.action);
    //编译子节点
    $compile().fromNode($node[0].childNodes).compile();
}
</code></pre>
<p></p>
<h4>$update</h4>
<p>$update()</p>
<p>手工同步数据到$view，一般用于定义指令：<br> </p>
<pre><code><br>$view.title = '1111';
$view.$update()
</code></pre>
<p></p>
<h4>$updateAsync</h4>
<p>$updateAsync()</p>
<p>与$update相同，但这个不是马上同步，而是后台异步去同步数据<br> </p>
<pre><code><br>$view.$updateAsync()
$view.title = '1111';
</code></pre>
<p></p>
<h4>$subs/$subscribe</h4>
<p>$subs(p, callback[, deep][, disposer])</p>
<p>添加一个订阅, $view是通过订阅方式/发布同步消息（观察模式）方式同步数据的。就是说，当调用$view.$update()时，$view会向所有订阅发送同步消息，当订阅收到信息后看看数据有没有改变，如果有改变就会同步数据；</p>
<p><strong>p</strong> 为观察的内容，可以属性名称或者一个方法<br><strong>callback</strong> 如果观察到数据改变，执行此方法<br><strong>deep</strong> 可选， 是否深比较， 默认false<br><strong>disposer</strong>, 可选，释放者， 如果此对象已释放， 订阅自动删除，默认为$view </p>
<p>通过属性名称订阅内容:<br> </p>
<pre><code><br>$view.title = '标题';
$view.titleLen = $view.title.length;

//订阅$view.title内容
$view.$subs('title', function(value){
  //如果titlen改变了，执行此function内容
  //value为title新内容
  $view.titleLen = value.length;
});
</code></pre>
<p></p>
<p>通过方法订阅内容:<br> </p>
<pre><code><br>//订阅$view.title内容
$view.$subs(function(){ return $view.title; }, function(value){
  $view.titleLen = value.length;
});
</code></pre>
<p></p>
<p>订阅内容作深比较:<br> </p>
<pre><code><br>$view.obj = { a: 1, b: 2 };
$view.$subs('obj', function(value){
  
  
}, true);
</code></pre>
<p></p>
<h4>$apply</h4>
<p>$apply(function)</p>
<p>执行方法，并自动同步数据</p>
<h4>$proxy</h4>
<p>$proxy(function)</p>
<p>与$apply一样自动同步数据，但不是立即执行，而返回一个代理方法<br> </p>
<pre><code><br>//正常我们手动同步数据
setTimeout(function(){
  $view.title = '标题';
  $view.$update();
});

//如果使用$apply就不用手动同步数据了
setTimeout(function(){
  $view.$apply(function(){
    $view.title = '标题';
  });
});

//如果使用$proxy就不用手动同步数据了
setTimeout($view.$proxy(function(){
  $view.title = '标题';
}));
</code></pre>
<p></p>
<h4>$isReady</h4>
<p>$view是否编译完成了，都准备好了, 可以正常写业务代码了</p>
<h4>onInitData</h4>
<p>onInitData(callback)</p>
<p>在$view环境准备好后发送onReady前用于收集数据，一般用于异步请求初始数据;</p>
<h4>onReady</h4>
<p>onReady(callback)</p>
<p>在onInitData事件请求完所有数据接收之后，这个代表当前$view准备好了，可以写业务代码了</p>
<h4>onReadyAll</h4>
<p>onReadyAll(callback)</p>
<p>这个事件代表$view和所有子孙$view都准备好后</p> 
<pre><code>&lt;div bg-action="action1" style="display:none;"&gt;
    {{title}}
    &lt;div bg-action="actionChild"&gt;
        {{title}}
    &lt;/div&gt;

&lt;/div&gt;
&lt;script&gt;
    var action1 = bingo.action(function ($view, $ajax) {
        $view.title = 'view1';

        //向后端请数据
        $view.onInitData(function () {

            $ajax('rest/user/list').success(function (rs) {

            }).post();

            $ajax('rest/role/list').success(function (rs) {

            }).post();
        });

        //如果有数据请求，等待所有数据请求完成后,$view ready
        $view.onReady(function () {
            $view.$getNode().show();
        });

        //$view ready和子孙都ready
        $view.onReadyAll(function () {
            console.log('onReadyAll');
        });

        $view.actionChild = bingo.action(function ($viewChild) {
            $viewChild.title = 'viewChild';

            //$viewChild ready
            $view.onReady(function () {
                console.log('viewChild ready');
            });
        });

    });
&lt;/script&gt;
</code></pre>
<h4>$using</h4>
<p>$using(url, callback)</p>
<p>动态加载js文件, 这个方法跟bingo.using用法是一样的，但在编译期间同步$view用的，所以在写指时最好用$view.$using来加载js;<br> </p>
<pre><code><br>$view.$using('action/demo/user/list', fucntion(){
  //这里写加载后处理代码
});
</code></pre>
<p></p>
<h4>$timeout</h4>
<p>$timeout(callback, time)<br> 这个方法跟setTimeout用法是一样的，但在编译期间同步$view用的，所以在写指时最好用$view.$timeout;<br> </p>
<pre><code><br>$view.$timeout(fucntion(){
  //这里写加载后处理代码
}, 1000);
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55668" class="sin_target">$viewnode</h5>
<div class="sin_text">
    					<p>$viewnode由框架编译时注入，在定义指令时才有效，在编译时如果有指令（如bg-action）的dom node，就会生成的对应个$viewnode；$viewnode主要管理$attr，如果不用遍历管理$attr几乎很少用；<br> </p>
<pre><code><br>&lt;div bg-action="action1"&gt;
    &lt;div&gt;
        {{time}}
    &lt;/div&gt;
    &lt;input type="button" value="刷新时间"
        bg-click="updateTime" /&gt;
&lt;/div&gt;
</code></pre>
<br>如上面html代码，编译后会生成两个**$nodeview**，分别是
<div>
 节点和，而且两个是**父子关系**，它们是根据dom node关系生成父子关系
 <p></p>
 <h3>属性与方法：</h3> 
 <hr>
 <h4>view</h4>
 <p>view()</p>
 <p>获取所属的view<br> </p>
 <pre><code><br>var view = $viewnode.view();
view.$udpate();
</code></pre>
 <p></p>
 <h4>parentViewnode</h4>
 <p>parentViewnode()</p>
 <p>获取所属的父viewnode<br> </p>
 <pre><code><br>var parent = $viewnode.parentViewnode();
</code></pre>
 <p></p>
 <h4>children</h4>
 <p>获取viewnode所有下级（子）viewnode<br> </p>
 <pre><code><br>var list = $viewnode.children;
var child= list[0];
</code></pre>
 <p></p>
 <h4>node</h4>
 <p>node()</p>
 <p>获取所对应dom node<br> </p>
 <pre><code><br>var node= $viewnode.node();
$(node).addClass('red');
</code></pre>
 <p></p>
 <h4>$getAttr</h4>
 <p>$getAttr(name)</p>
 <p>获取$attr, 详细请参考$attr<br> </p>
 <pre><code><br>var $attr= $viewnode.$getAttr('bg-action');
var value = $attr.$value();
</code></pre>
 <p></p>
 <h4>$html</h4>
 <p>$html([html])</p>
 <p>获取或设置html, 如果设置html，会自动编译<br> </p>
 <pre><code><br>var html = $viewnode.$html();
html = '&lt;div bg-action="action1"&gt;&lt;/div&gt;';
$viewnode.$html(html);
</code></pre>
 <p></p>
 <h4>attrList</h4>
 <p>获取viewnode所有$attr<br> </p>
 <pre><code><br>var list = $viewnode.attrList;
var $attr = list[0];
var value = $attr.$value();
</code></pre>
 <p></p>
</div>
			</div>

																						<h5 id="text_55669" class="sin_target">$attr</h5>
<div class="sin_text">
    					<p>$attr由框架编译时注入，在定义指令时才有效，在编译时会为每个指令（如bg-action）对应生成一个$attr，在定义指令时要通过$attr提供的接口来读取相关的绑定信息:<br> </p>
<pre><code><br>//定义指令bg-text
bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, $node) {
        
        var _set = function (val) {
            $node.text(bingo.toStr(val));
        };

        //订阅执行结果， 如果执行结果改变时，同步数据
        $attr.$subsResults(function (newValue) {
            _set(newValue);
        });

        //根据执行结果初始结果
        $attr.$initResults(function (value) {
            _set(value);
        });

    }];
});
</code></pre>
<br>如上面代码，是定义指令**bg-text**，它通过$attr提供的$initResults来做初始工作、$subsResults来订阅数据从而同步数据；
<p></p>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view()</p>
<p>获取所属的view<br> </p>
<pre><code><br>var view = $attr.view();
view.$udpate();
</code></pre>
<p></p>
<h4>viewnode</h4>
<p>viewnode()</p>
<p>获取所属viewnode<br> </p>
<pre><code><br>var viewnode= $attr.viewnode();
</code></pre>
<p></p>
<h4>node</h4>
<p>node()</p>
<p>获取所在的dom node<br> </p>
<pre><code><br>var node= $attr.node();
$(node).addClass('red');
</code></pre>
<p></p>
<h4>$attrValue</h4>
<p>$attrValue([str])</p>
<p>获取或设置dom node 属性原始内容</p>
<p><strong>str</strong>：可选，要设置的内容<br><code>注意：尽量不要使用这方法重复设置原始内容，会产生重新编译，如果一定设置最好在$value、$results等操作之前</code><br> </p>
<pre><code><br>&lt;div bg-text="title"&gt;&lt;/div&gt;
&lt;script&gt;
...
var prop = $attr.$attrValue()
prop === 'title'
...
$attr.$attrValue('username');
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$eval</h4>
<p>$eval([event])</p>
<p>以属性原始内容为脚本执行，可以返回结果, 多用于事件绑定</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>&lt;div bg-click="clickFn"&gt;&lt;/div&gt;
&lt;script&gt;
...
$view.clickFn = function(e){
  return false;
};
...
$(node).click(function(e){
  return $attr.$eval(e);
});
...
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$results</h4>
<p>$results([event])</p>
<p>以属性原始内容为脚本执行并返回结果（即返回执行结果），一般用于模糊绑定(可能是$view属性、JS语句…)</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>&lt;div bg-text="title + '111'"&gt;&lt;/div&gt;
&lt;script&gt;
...
$view.title = '标题';
var res= $attr.$results();
res=== '标题111'
...
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$value</h4>
<p>$value([value])</p>
<p>以属性原始内容为$view的属性名称，设置或获取$view的属性值，一般用于$view的属性绑定，如bg-model</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>value</strong>：可选，要设置的属性值<br> </p>
<pre><code><br>&lt;div bg-text="title"&gt;&lt;/div&gt;
&lt;script&gt;
...
$view.title = '标题';
var val= $attr.$value();
val === '标题';
val === $view.title
....
$attr.$value('新标题')
val= $attr.$value();
val=== '新标题';
val === $view.title
...
&lt;/script&gt;
</code></pre>
<p></p>
<h4>$init</h4>
<p>$init(p, fn)</p>
<p>定义指令时用，属性接收到初始化请求时会被调用；</p>
<p><strong>p</strong>：订阅内容，可以属性名称或function(){ return datas; }</p>
<p><strong>fn</strong>：初始化操作, function(value){}</p> 
<pre><code>//定义指令bg-text
bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, $node) {
        
        //初始化
        $attr.$init(function () {
            //订阅内容
            return $attr.$results();
        }, function (value) {
            //根据value做初始化操作
            //设置$node text内容
            $node.text(value);
        });

    }];
});
</code></pre>
<h4>$initResults</h4>
<p>$initResults(fn)</p>
<p>对$init进行简化封装，订阅**执行内容**进行初始化，使用场景是一样，用于初始化；</p>
<p><strong>fn</strong>：初始化操作, function(value){}<br> </p>
<pre><code><br>//初始化
$attr.$initResults(function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p></p> 
<pre><code>//初始化
$attr.$init(function () {
    //订阅内容
    return $attr.$results();
}, function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p>上面两段代码是等效的</p>
<h4>$initValue</h4>
<p>$initValue(fn)</p>
<p>对$init进行简化封装，订阅**属性内容**进行初始化，使用场景是一样，用于初始化；</p>
<p><strong>fn</strong>：初始化操作, function(value){}<br> </p>
<pre><code><br>//初始化
$attr.$initValue(function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p></p> 
<pre><code>//初始化
$attr.$init(function () {
    //订阅内容
    return $attr.$value();
}, function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p>上面两段代码是等效的</p>
<h4>$subs</h4>
<p>$subs(p, fn)</p>
<p>定义指令时用，属性接收到同步请求时会被调用；</p>
<p><strong>p</strong>：订阅内容，可以属性名称或function(){ return datas; }</p>
<p><strong>fn</strong>：同步数据操作, function(value){}</p> 
<pre><code>//定义指令bg-text
bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, $node) {
        
        //订阅内容，同步数据时用
        $attr.$subs(function () {
            //订阅内容
            return $attr.$results();
        }, function (value) {
            //根据value做初始化操作
            //设置$node text内容
            $node.text(value);
        });

    }];
});
</code></pre>
<h4>$subsResults</h4>
<p>$subsResults(fn)</p>
<p>对$subs进行简化封装，订阅**执行内容**进行同步数据，使用场景是一样，用于同步数据；</p>
<p><strong>fn</strong>：同步数据操作, function(value){}<br> </p>
<pre><code><br>//订阅内容，同步数据时用
$attr.$subsResults(function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p></p> 
<pre><code>//订阅内容，同步数据时用
$attr.$subs(function () {
    //订阅内容
    return $attr.$results();
}, function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p>上面两段代码是等效的</p>
<h4>$subsValue</h4>
<p>$subsValue(fn)</p>
<p>对$subs进行简化封装，订阅**属性内容**进行同步数据，使用场景是一样，用于同步数据；</p>
<p><strong>fn</strong>：同步数据操作, function(value){}<br> </p>
<pre><code><br>//订阅内容，同步数据时用
$attr.$subsValue(function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p></p> 
<pre><code>//订阅内容，同步数据时用
$attr.$subs(function () {
    //订阅内容
    return $attr.$value();
}, function (value) {
    //设置$node text内容
    $node.text(value);
});
</code></pre>
<p>上面两段代码是等效的</p>
			</div>

																						<h5 id="text_55670" class="sin_target">$node</h5>
<div class="sin_text">
    					<p>使用时注入，这个是一个jQuery对象，不同地方注入有不同结果；在action时获取到$view节点的jQuery对象，在定义指令时获取到指令所有dom node的jQuery对象<br> </p>
<pre><code><br>var action = bingo.action(function($view, $node){
  $node[0] === $view.$getNode()[0];
});

bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, $node) {
       $attr.node() === $node[0];
    }];
});
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55671" class="sin_target">node</h5>
<div class="sin_text">
    					<p>使用时注入，这个是一个原生的dom node，不同地方注入有不同结果；在action时获取到$view所在的dom node，在定义指令时获取到指令所有dom node<br> </p>
<pre><code><br>var action = bingo.action(function($view, node){
  node === $view.$getNode()[0];
});

bingo.command('bg-text', function () {

    return ['$attr', '$node', function ($attr, node) {
       $attr.node() === node;
    }];
});
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55672" class="sin_target">$rootView</h5>
<div class="sin_text">
    					<p>使用时注入，获取到框架的根view</p>
			</div>

																						<h5 id="text_55673" class="sin_target">$compile</h5>
<div class="sin_text">
    					<p>使用时注入，使用于动态编译；其实框架提供的基础指令，如果使用正确，都可以满足太部分动态加载编译需求；但某些特殊情况还是要$compile满足，而且基础指令也是通过它来动态加载编译的，如在定义bg-action里有用到的$compile：<br> </p>
<pre><code><br>bingo.command('bg-action', function () {

    return {
        compile: ['$view', '$compile', '$node', '$attr', function ($view, $compile, $node, $attr) {
            ...
            $compile().fromNode($node[0].childNodes).compile();
            ...
        }]
    };
});

</code></pre>
<p></p>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view()</p>
<p>获取所属的view<br> </p>
<pre><code><br>var view = $compile.view();
view.$udpate();
</code></pre>
<p></p>
<h4>fromNode</h4>
<p>fromNode(node)</p>
<p>编译内容来自dom node</p>
<p><strong>node</strong>：可以是一个/一组dom node<br> </p>
<pre><code><br>var jo = $(document.body);
//更改html
jo.html('&lt;div bg-text="title"&gt;&lt;div&gt;');
//编译子节点
$compile().fromNode(jo[0].childNodes).compile();

</code></pre>
<p></p>
<h4>fromJquery</h4>
<p>fromJquery(jquerySelector)</p>
<p>编译内容来自jQuery查询</p>
<p><strong>jquerySelector</strong>：jQuery查询语法<br> </p>
<pre><code><br>var jo = $(document.body);
//更改html
jo.html('&lt;div bg-text="title"&gt;&lt;div&gt;');
//编译子节点
$compile().fromJquery(jo.children()).compile();
</code></pre>
<p></p>
<h4>fromHtml</h4>
<p>fromHtml(html)</p>
<p>编译内容来自html模板</p>
<p><strong>html</strong>：html模板<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromHtml('&lt;div bg-text="title"&gt;&lt;div&gt;').appendTo(jo).compile();
</code></pre>
<p></p>
<h4>fromUrl</h4>
<p>fromUrl(url)</p>
<p>编译内容来自远程模板</p>
<p><strong>url</strong>：从url加载模板，并编译<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').appendTo(jo).compile();
</code></pre>
<p></p>
<h4>appendTo</h4>
<p>appendTo(jqSelector)</p>
<p>编译后添加到dom node，成为它的子节点</p>
<p><strong>jqSelector</strong>：jQuery查询语法<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').appendTo(jo).compile();
</code></pre>
<p></p>
<h4>action</h4>
<p>action(fn)</p>
<p>给下一级新的view注入action，如果没有新view，此action会无效</p>
<p><strong>action</strong>：添加一个action<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').action(function($view){
   $view.onReady(function(){});
}).appendTo(jo).compile();
</code></pre>
<p></p>
<h4>withData</h4>
<p>withData(data)</p>
<p>设置withData名字空间</p>
<p><strong>data</strong>：一个withData object<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译, 注意这里**title**会优先谋取withData的title,而不是view的title
$compile().fromHtml('&lt;div bg-text="title"&gt;&lt;div&gt;').withData({title:'withTitle'}).appendTo(jo).compile();
</code></pre>
<p></p>
<h4>withDataList</h4>
<p>withDataList(datas)</p>
<p>设置一组名字空间，要结合$render使用，请参考bg-for的定义原码</p>
<p><strong>datas</strong>：一组widthData List<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
var html = '';
var withDataList = [];//收集数据
html = renderObj.render([1,2,3], 'item', null, -1, withDataList);
$compile().fromHtml(html).withDataList(withDataList).appendTo(jo).compile();
</code></pre>
<p></p>
<h4>stop</h4>
<p>stop(true/false)</p>
<p>是否停止编译，一般用于从url加载模板方式编译用；</p> 
<pre><code>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
var cmp = $compile().fromUrl('view/demo/user/list').appendTo(jo).compile();
cmp.stop(true);
</code></pre>
<h4>compile</h4>
<p>compile()</p>
<p>执行编译</p> 
<pre><code>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').appendTo(jo).compile();
</code></pre>
<h4>onCompilePre</h4>
<p>onCompilePre(callback)</p>
<p>编译前事件</p>
<p><strong>callback</strong>：事件执行内容, function(jNode){}；<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').onCompilePre(function(jNode){
   jNode.addClass('active');
}).appendTo(jo).compile();

</code></pre>
<p></p>
<h4>onCompiled</h4>
<p>onCompiled(callback)</p>
<p>编译后事件</p>
<p><strong>callback</strong>：事件执行内容, function(jNode){}；<br> </p>
<pre><code><br>var jo = $(document.body);
//清除原来内容
jo.html('');
//编译
$compile().fromUrl('view/demo/user/list').onCompiled(function(jNode){
   jNode.addClass('active');
}).appendTo(jo).compile();

</code></pre>
<p></p>
			</div>

																						<h5 id="text_55674" class="sin_target">$bindContext</h5>
<div class="sin_text">
    					<h4>$bindContext</h4>
<p>$bindContext(bindText[, node][, withData])</p>
<p>绑定内容解释器，饰物$attr也是继承这个对象，是本框架绑定核心对象，它可以用解释高级UI组件的参数内容（如grid的列配置）</p>
<p><strong>bindText</strong>：绑定内容;<br><strong>node</strong>：可选，传入内容所在的node<br><strong>widthData</strong>：可选，设置名字空间 </p> 
<pre><code>var action = bingo.action(function($view, $bindContext){
  $view.title = '标题';

  //解释title内容
  var bind = $bindContext('title');
  var val = bind.$value();
  val === $view.title;

  //下去是解释title内容长度
  var bind = $bindContext('title | len');
  var val = bind.$value();
  val === 2;
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view()</p>
<p>获取所属的view</p>
<h4>node</h4>
<p>node()</p>
<p>获取所在的dom node</p>
<h4>$prop</h4>
<p>$prop([str])</p>
<p>获取或设置dom node 属性原始内容</p>
<p><strong>str</strong>：可选，要设置的内容<br><code>注意：尽量不要使用这方法重复设置原始内容，会产生重新编译，如果一定设置最好在$value、$results等操作之前</code><br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext('title');
  var val = bind.$prop();
  val === 'title';
</code></pre>
<p></p>
<h4>$eval</h4>
<p>$eval([event])</p>
<p>以属性原始内容为脚本执行，可以返回结果, 多用于事件绑定</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext('alert(title)');
  bind.$eval();
  
</code></pre>
<p></p>
<h4>$results</h4>
<p>$results([event])</p>
<p>以属性原始内容为脚本执行并返回结果（即返回执行结果），一般用于模糊绑定(可能是$view属性、JS语句…)</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext('title + "1111"');
  var val = bind.$results();
  val === $view.title + "1111";
</code></pre>
<p></p>
<h4>$value</h4>
<p>$value([value])</p>
<p>以属性原始内容为$view的属性名称，设置或获取$view的属性值，一般用于$view的属性绑定，如bg-model</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>value</strong>：可选，要设置的属性值<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext('title');
  var val = bind.$value();
  val === $view.title;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55675" class="sin_target">$nodeContext</h5>
<div class="sin_text">
    					<h4>$nodeContext</h4>
<p>$nodeContext(node[, withData])</p>
<p><strong>$nodeContext</strong> 解释dom node绑定内容，它也是$bindContext集合，它可以用解释高级UI组件的参数内容（如grid的列配置）</p>
<p><strong>node</strong>：要解释的的node<br><strong>widthData</strong>：可选，设置名字空间 </p> 
<pre><code>&lt;grid&gt;
    &lt;column name="id" text="ID"&gt;&lt;/column&gt;
    &lt;column name="title" text="主题" formatter="formatTitle"&gt;&lt;/column&gt;
&lt;/grid&gt;
&lt;script&gt;
bingo.command('grid', function () {
    return {
        //模板
        tmpl: '&lt;div&gt;&lt;/div&gt;',
        replace: true,
        view: true,
        //是否编译子节点, 默认为true
        compileChild: false,
        compilePre: function ($view, $node, $nodeContext) {
            $view.formatTitle = function () { alert('aaaa'); };
            var colList = [];

            //解释column
            $node.find('column').each(function () {
                var bind = $nodeContext(this);
                var formatter = bind.$results('formatter');
                var name = bind.$prop('name');
                var text = bind.$prop('text');
                colList.push([formatter, name, text]);
            });

            console.log(colList);

        }
    };
});
&lt;/script&gt;
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view()</p>
<p>获取所属的view<br> </p>
<pre><code><br>var view = $attr.view();
view.$udpate();
</code></pre>
<p></p>
<h4>node</h4>
<p>node()</p>
<p>获取所在的dom node<br> </p>
<pre><code><br>var node= $attr.node();
$(node).addClass('red');
</code></pre>
<p></p>
<h4>$prop</h4>
<p>$prop(name[, str])</p>
<p>获取或设置dom node 属性原始内容</p>
<p><strong>name</strong>：属性名称<br><strong>str</strong>：可选，要设置的内容<br><code>注意：尽量不要使用这方法重复设置原始内容，会产生重新编译，如果一定设置最好在$value、$results等操作之前</code><br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext($('&lt;div testbind="title"&gt;&lt;/div&gt;')[0]);
  bind.$prop('testbind') == 'title';
</code></pre>
<p></p>
<h4>$eval</h4>
<p>$eval(name[, event])</p>
<p>以属性原始内容为脚本执行，可以返回结果, 多用于事件绑定</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>name</strong>：属性名称<br><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext($('&lt;div testbind="alert(title)"&gt;&lt;/div&gt;')[0]);
  bind.$eval('testbind');
</code></pre>
<p></p>
<h4>$results</h4>
<p>$results(name, [,event])</p>
<p>以属性原始内容为脚本执行并返回结果（即返回执行结果），一般用于模糊绑定(可能是$view属性、JS语句…)</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>name</strong>：属性名称<br><strong>event</strong>：可选，要传入事件<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext($('&lt;div testbind="title"&gt;&lt;/div&gt;')[0]);
  var val = bind.$results('testbind');
  val === $view.title;
</code></pre>
<p></p>
<h4>$value</h4>
<p>$value(name[,value])</p>
<p>以属性原始内容为$view的属性名称，设置或获取$view的属性值，一般用于$view的属性绑定，如bg-model</p>
<p><code>注意：如果相关属性在$view没有定义，会去window查询</code></p>
<p><strong>name</strong>：属性名称<br><strong>value</strong>：可选，要设置的属性值<br> </p>
<pre><code><br>  $view.title = '标题';

  //下去是解释title内容
  var bind = $bindContext($('&lt;div testbind="title"&gt;&lt;/div&gt;')[0]);
  var val = bind.$value('testbind');
  val === $view.title;
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55676" class="sin_target">$ajax</h5>
<div class="sin_text">
    					<h4>$ajax</h4>
<p>$ajax(url)</p>
<p>向服务器后台异步请求资源数据</p>
<p><strong>url</strong>：资源route url </p> 
<pre><code>var action = bingo.action(function($view, $ajax){
  
  $view.userList = [];
  $ajax('rest/user/getUserList').success(function(r){
    $view.userList = r;
  }).post();
  
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view([view])</p>
<p>获取或设置ajax所属view，如果view已经销毁，ajax将会强制停止</p>
<p><strong>view</strong>：要设置的view；</p>
<h4>success</h4>
<p>success(callback)</p>
<p>请求成功事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p>
<h4>error</h4>
<p>error(callback)</p>
<p>请求失败事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p>
<h4>alway</h4>
<p>alway(callback)</p>
<p>请求成功或失败事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p> 
<pre><code>var action = bingo.action(function($view, $ajax){
  
  $view.userList = [];
  $ajax('rest/user/getUserList').success(function(r){
    $view.userList = r;
  }).error(function(r){
    console.log(r);
  }).alway(function(r){
    console.log(r);
  }).post();
  
});
</code></pre>
<h4>async</h4>
<p>async(true/false)</p>
<p>获取或设置是否异步，默认true</p>
<h4>dataType</h4>
<p>dataType(type)</p>
<p>请求数据类型，默认json, 可以是xml,html,json,jsonp,text</p>
<h4>param</h4>
<p>param(object)</p>
<p>请求参数</p>
<h4>get</h4>
<p>get()</p>
<p>使用get方式请求数据</p>
<h4>post</h4>
<p>post()</p>
<p>使用post方式请求数据</p> 
<pre><code>var action = bingo.action(function($view, $ajax){
  
  $view.userList = [];
  $ajax('rest/user/getUserList').success(function(r){
    $view.userList = r;
  })
  .dataType('text').async(true).param({title:'标题'}).post();
  
});
</code></pre>
<h4>fromOther</h4>
<p>fromOther(ajax)</p>
<p>参考其它ajax的属性</p> 
<pre><code>var ajax1 = bingo.ajax.ajaxClass.NewObject()
var ajax2 = bingo.ajax.ajaxClass.NewObject();
ajax2.fromOther(ajax1);
</code></pre>
<h4>cacheTo</h4>
<p>cacheTo(object)</p>
<p>缓存到object, 默认为null, 不缓存</p>
<h4>cacheMax</h4>
<p>cacheMax(num)</p>
<p>缓存最大记录数量，设置了cacheTo这个参数才有效，默认无限</p>
<h4>cacheQurey</h4>
<p>cacheQurey(boolean)</p>
<p>是否包函url query部分作为key 缓存数据, 默认true</p> 
<pre><code> var _cacheObj = {};
var action = bingo.action(function($view, $ajax){
  
  $view.userList = [];

  //下面缓存数据到_cacheObj，如果下次相同请求，直接读取缓存，不向服务器请求
  $ajax('rest/user/getUserList').success(function(r){
    $view.userList = r;
  }).cacheTo(_cacheObj).cacheMax(100).cacheQurey(true).post();
  
});
</code></pre>
			</div>

																						<h5 id="text_55677" class="sin_target">$tmpl</h5>
<div class="sin_text">
    					<h4>$tmpl</h4>
<p>$tmpl(url)</p>
<p>主要负责管理html模板资源，本框架所有html模板资源都由$tmpl负责加载，它处理了一个缓存模板优化等；</p>
<p><strong>url</strong>：资源route url </p> 
<pre><code>var action = bingo.action(function($view, $tmpl, $complie){
  
  $tmpl('view/demo/user/list').success(function(html){
    $complie().formHtml(html).appendTo(document.body).complie();
  }).post();
  
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>view</h4>
<p>view([view])</p>
<p>获取或设置ajax所属view，如果view已经销毁，ajax将会强制停止</p>
<p><strong>view</strong>：要设置的view；</p>
<h4>success</h4>
<p>success(callback)</p>
<p>请求成功事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p>
<h4>error</h4>
<p>error(callback)</p>
<p>请求失败事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p>
<h4>alway</h4>
<p>alway(callback)</p>
<p>请求成功或失败事件</p>
<p><strong>callback</strong>：处理方法callback(rs)；</p> 
<pre><code>var action = bingo.action(function($view, $ajax){
  
  $tmpl('view/demo/user/list').success(function(r){
    console.log(r);
  }).error(function(r){
    console.log(r);
  }).alway(function(r){
    console.log(r);
  }).post();
  
});
</code></pre>
<h4>async</h4>
<p>async(true/false)</p>
<p>获取或设置是否异步，默认true</p>
<h4>param</h4>
<p>param(object)</p>
<p>请求参数</p>
<h4>get</h4>
<p>get()</p>
<p>使用get方式请求数据</p>
<h4>post</h4>
<p>post()</p>
<p>使用post方式请求数据</p> 
<pre><code>var action = bingo.action(function($view, $ajax){
  
  $tmpl('view/demo/user/list').success(function(r){
    console.log(r);
  })
  .dataType('text').async(true).param({title:'标题'}).post();
  
});
</code></pre>
			</div>

																						<h5 id="text_55678" class="sin_target">$factory</h5>
<div class="sin_text">
    					<h4>$factory</h4>
<p>$factory(p)</p>
<p><strong>$factory</strong> 是注入内容解释</p>
<p><strong>p</strong>：注入名称或function </p> 
<pre><code>var action = bingo.action(function($view, $factory){
  $view.title = '标题';

  //通过注入名称，解释出相关的注入
  var $node =  $factory('$node').inject();

  //临时注入
  $factory(function($node){
     $node.addClass('action');
   }).inject()
});
</code></pre>
			</div>

																						<h5 id="text_55679" class="sin_target">$var</h5>
<div class="sin_text">
    					<h4>$var</h4>
<p>$var(p[, owner])</p>
<p>定义一个$var变量，它支持可观察特性和自定义get/set，实现变量与绑定同步数据，不用同步整个view，提高绑定性能;</p>
<p><strong>p</strong>：初始化值，可以任意数据；<br><strong>owner</strong>：设置$var变量的拥有者，默认为null，即会自动变更拥有者；</p> 
<pre><code>&lt;div bg-action="action1"&gt;
    &lt;div bg-text="title"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
var action1 = bingo.action(function($view, $var){
    //定义title为$var变量，并初始化值
    $view.title = $var('标题');

    setTimeout(function(){
        //只要设置title值, 就可以直接同步到$view，不用$view.$update来同步数据
        $view.title('标题改变');
    }, 1000);
});
&lt;/script&gt;
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>$subs</h4>
<p>$subs(callback[, disposer])</p>
<p>订阅变更信息(当在赋值时, 只有值改变了, 才接收订阅信息)</p>
<p><strong>callback</strong>：接收到订阅信息，执行处理<br><strong>disposer</strong>：如果disposer已经销毁，些订阅信息失效；</p> 
<pre><code>var text = $var('文本');
text.$subs(function(value){
  console.log('text 已经改变为：'+value);
});
text('新文本');
</code></pre>
<h4>$assign</h4>
<p>$assign(callback[, disposer])</p>
<p>订阅赋值信息(当在赋值时, 不理值是否改变, 都接收订阅信息)</p>
<p><strong>callback</strong>：接收到订阅信息，执行处理<br><strong>disposer</strong>：如果disposer已经销毁，些订阅信息失效；</p> 
<pre><code>var text = $var('文本');
text.$assign(function(value){
  console.log('text 已经赋值为：'+value);
});
text('文本');
</code></pre>
<h4>$off</h4>
<p>$off(callback)</p>
<p>订阅赋值信息，当$var变量有设置值并且不理有没**变更**，会发布赋值信息</p>
<p><strong>callback</strong>：可选，取消订阅信息，如果为空将取消所有订阅</p> 
<pre><code>var text = $var('文本');
var fn = function(value){
  console.log('text 已经赋值为：'+value);
}
text.$assign(fn);
text.$off(fn);
text('文本');
</code></pre>
<h4>$setChange</h4>
<p>$setChange(isChanged)</p>
<p>强制设置改变状态，从需重新发布所有订阅信息</p>
<p><strong>isChanged</strong>：可选，可以改变，默认为true</p> 
<pre><code>var text = $var('文本');
var fn = function(value){
  console.log('text 已经赋值为：'+value);
}
text.$assign(fn);
text.$setChange();
</code></pre>
<h4>$set</h4>
<p>$set(fn)</p>
<p>制定赋值行为</p>
<p><strong>fn</strong>：制定赋值行为方法，function(value){}</p> 
<pre><code>$view.text = $var('文本');
$view.text.$set(function(value){
   //this.value为默认保存值地方
   this.value = value;
   //取得text的owner, 这里为$view
   this.owner === $view;
});
</code></pre>
<h4>$get</h4>
<p>$get(fn)</p>
<p>制定取值行为</p>
<p><strong>fn</strong>：制定取值行为方法，function(){}</p> 
<pre><code>$view.text = $var('文本');
$view.text.$get(function(){
   //this.value为默认保存值地方
   return this.value;
});
</code></pre>
			</div>

																						<h5 id="text_55680" class="sin_target">$model</h5>
<div class="sin_text">
    					<h4>$model</h4>
<p>$model(obj)</p>
<p>数据模型，负责处理数据模型收集和绑定处理，其实也可以认为$var集合体:<br> </p>
<pre><code><br>var model = $model({
  name:'张三',
  age:25
});
</code></pre>
<br>上面定义可以认为相等于：
<br> 
<pre><code><br>var model ={
   name:$var('张三'),
   age:$var(25),
   toObject:function(){}
   formObject:function(obj){}
};
</code></pre>
<p></p>
<h3>属性与方法：</h3> 
<hr>
<h4>formObject</h4>
<p>formObject(obj)</p>
<p>从一个对象设置model值</p>
<p><strong>obj</strong>：从obj对象设置model值</p> 
<pre><code>var model = $model({
  name:'张三',
  age:25
});
model.formObject({
  name:'李四',
  age:28
});
</code></pre>
<h4>toObject</h4>
<p>toObject([obj])</p>
<p>将model转成变通object</p>
<p><strong>obj</strong>：可选,将model内容推送到obj</p> 
<pre><code>var model = $model({
  name:'张三',
  age:25
});
//model转成普通object
var obj = model.toObject();

var obj1 = {};
model.toObject(obj1);
</code></pre>
			</div>

																						<h5 id="text_55681" class="sin_target">$observer</h5>
<div class="sin_text">
    					<h4>$observer</h4>
<p>观察者，框架会为每个$view创建一个观察者（observer），使用它的订阅信息及发布信息来实现绑定数据同步；</p> 
<pre><code>var action = bingo.action(function($view, $observer){
  $view.title = '标题';

  //订阅信息,title
  $observer.subscribe('title', function(value){
    console.log(value);
  });

  //修改title并发布信息
  $view.title = '新标题';
  $observer.publish();
  
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>subscribe</h4>
<p>subscribe(context, callback[, deep][, disposer])</p>
<p>订阅信息。</p>
<p><strong>context</strong>：要订阅的内容，可以$view的属性名称或function<br><strong>callback</strong>：订阅的内容改变时执行相关处理<br><strong>deep</strong>：订阅的内容是否深比较，默认false<br><strong>disposer</strong>：释放者，如果这对象已经释放，这订阅自动取消 </p>
<h4>unSubscribe</h4>
<p>unSubscribe(callback)</p>
<p>取消订阅信息。</p>
<p><strong>callback</strong>：订阅的内容的执行方法 </p>
<h4>publish</h4>
<p>publish()</p>
<p>发布信息。</p>
<h4>publishAsync</h4>
<p>publishAsync()</p>
<p>发布信息。</p> 
<pre><code>  $view.obj = { title:'标题', age: 23};

  var subsFCallback = function(value){
    console.log('obj', value);
  };

  //订阅信息obj, 并深比较
  $observer.subscribe('obj', subsFCallback , true);

  //与上面订阅内容是一样的；
  $observer.subscribe(function(){ return $view.obj; }, subsFCallback, true);


  //修改标题，发布信息
  $view.obj.title = '新标题';
  $observer.publish();

  //取消subsFCallback订阅
  $observer.unSubscribe(subsFCallback);
</code></pre>
			</div>

																						<h5 id="text_55682" class="sin_target">$subs($subscribe)</h5>
<div class="sin_text">
    					<h4>$subs($subscribe)</h4>
<p>$subs(context, callback[, deep])</p>
<p>订阅信息，是$observer的subscribe方法注入，具体用法还可参考$observer。</p>
<p><strong>context</strong>：要订阅的内容，可以$view的属性名称或function<br><strong>callback</strong>：订阅的内容改变时执行相关处理<br><strong>deep</strong>：订阅的内容是否深比较，默认false</p> 
<pre><code>var action = bingo.action(function($view, $subs){
  $view.title = '标题';

  //订阅信息,title
  $subs('title', function(value){
    console.log(value);
  });
  //与上面订阅内容是一样
  $subs(function(){ return $view.title; }, function(value){
    console.log(value);
  });

  //修改title并同步数据
  $view.title = '新标题';
  $observer.update();
  
});
</code></pre>
			</div>

																						<h5 id="text_55683" class="sin_target">$module</h5>
<div class="sin_text">
    					<h4>$module($subscribe)</h4>
<p>$module([moduleName])</p>
<p>获取一个模块module。</p>
<p><strong>moduleName</strong>：可选，模块名称，默认返回当前模块；</p> 
<pre><code>var action = bingo.action(function($view, $module){
   var curModule = $module();

   var demoModule = $module('demo');
  
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>$service</h4>
<p>$service(serviceName)</p>
<p>取得模块里的服务(service)。</p>
<p><strong>serviceName</strong>：服务名称；</p> 
<pre><code>var action = bingo.action(function($view, $module, userService){
   //userService是当前模块，可以直接注入;

   var curModule = $module();
   var userServiceNew = curModule.$service('userService');


   //demoService在其他模块里，只能通过$module来获取
   var demoModule = $module('demo');
   var demoService = demoModule.$service('demoService');
  
});
</code></pre>
<h4>$controller</h4>
<p>$controller(controllerName)</p>
<p>取得模块里的控制器(controller)。</p>
<p><strong>controllerName</strong>：控制器名称；</p> 
<pre><code>var action = bingo.action(function($view, $module){
   var curModule = $module();
   var userCtrl= curModule.$controller('user');
});
</code></pre>
<h4>$controller.$action</h4>
<p>$controller.$action(actionName)</p>
<p>取得模块里的控制器(service)。</p>
<p><strong>actionName</strong>：控制器名称；</p> 
<pre><code>var action = bingo.action(function($view, $module){
   var curModule = $module();
   var userCtrl= curModule.$controller('user');
   //执行userListAct, 实现两个action合并
   userCtrl.$action('list');
});
</code></pre>
			</div>

																						<h5 id="text_55684" class="sin_target">$route</h5>
<div class="sin_text">
    					<h4>$route</h4>
<p>$route(routeUrl)</p>
<p>route url解释成最终url</p>
<p><strong>routeUrl</strong>：原始route url</p> 
<pre><code>bingo.route('view', {
    //路由地址
    url: 'view/{module}/{controller}/{action}',
    //路由转发到地址
    toUrl: 'modules/{module}/views/{controller}/{action}.html',
    //默认值
    defaultValue: { module: '', controller: '', action: '' }
});

var action = bingo.action(function($view, $route){
  var url = $route('view/demo/user/list');
  url == 'modules/demo/views/user/list.html';
});
</code></pre>
			</div>

																						<h5 id="text_55685" class="sin_target">$routeContext</h5>
<div class="sin_text">
    					<h4>$routeContext</h4>
<p>$routeContext(routeUrl)</p>
<p>route url解释成最终route 内容</p>
<p><strong>routeUrl</strong>：原始route url</p> 
<pre><code>bingo.route('view', {
    //路由地址
    url: 'view/{module}/{controller}/{action}',
    //路由转发到地址
    toUrl: 'modules/{module}/views/{controller}/{action}.html',
    //默认值
    defaultValue: { module: '', controller: '', action: '' }
});

var action = bingo.action(function($view, $route){
  var routeContext = $routeContext('view/demo/user/list');
  //返回routeContext内容如下:
  routeContext == {
                name:'view',
                url:'view/demo/user/list',
                toUrl:'modules/demo/views/user/list.html',
                params:{ module: 'demo', controller: 'user', action: 'list' },
                actionContext:function(){...}
            };
});
</code></pre>
<h3>routeContext属性与方法：</h3> 
<hr>
<h4>name</h4>
<p>取得route名称。</p>
<h4>url</h4>
<p>原始route地址。</p>
<h4>toUrl</h4>
<p>解释后的最终url。</p>
<h4>params</h4>
<p>解释出来的参数。</p>
<h4>actionContext</h4>
<p>根据参数(params)生成action内容。</p> 
<pre><code>var action = bingo.action(function($view, $route){
  var routeContext = $routeContext('view/demo/user/list');
  var actionContext = routeContext.actionContext();
  //根据解释出来的params参数生成，以下action相关的信息
  actionContext  == {action:null, controller: null, module:null};
});
</code></pre>
			</div>

																						<h5 id="text_55686" class="sin_target">$location</h5>
<div class="sin_text">
    					<h4>$location</h4>
<p>$location</p>
<p>获取当前route的loctaion信息，一般结合bg-route使用</p> 
<pre><code>&lt;div bg-route="view/demo/user/list"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
  var url = $location.url();
  url === 'view/demo/user/list';
  var params = $location.params();
  params === { module: 'demo', controller: 'user', action: 'list' };
});
&lt;/script&gt;
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>url</h4>
<p>url()</p>
<p>获取当前route url</p>
<h4>queryParams</h4>
<p>queryParams()</p>
<p>获取当前route url 的参数</p>
<h4>href</h4>
<p>href(url[, target])</p>
<p>更改route链接</p>
<h4>reload</h4>
<p>reload([, target])</p>
<p>重新加载</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
  //链接当前route到view/demo/user/info
  $location.href('view/demo/user/info');

  //链接route 'main'到view/demo/user/info
  $location.href('view/demo/user/info', 'main');
});
&lt;/script&gt;
</code></pre>
<h4>ownerNode</h4>
<p>ownerNode()</p>
<p>获取bg-route所有dom node的jQuery对象</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
  $location.ownerNode().addClass('active');
});
&lt;/script&gt;
</code></pre>
<h4>views</h4>
<p>views()</p>
<p>获取location下面所有views</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
   var viewList = $location.views();
});
&lt;/script&gt;
</code></pre>
<h4>close</h4>
<p>close()</p>
<p>关闭location，既是删除bg-route dom node</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
   $location.close()
});
&lt;/script&gt;
</code></pre>
<h4>onChange</h4>
<p>onChange(callback)</p>
<p>链接变更事件</p>
<p><strong>callback</strong>，事件执行callback(url)</p>
<h4>onLoaded</h4>
<p>onLoaded(callback)</p>
<p>bg-route加载完成后事件</p>
<p><strong>callback</strong>，事件执行callback(url)</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
  $location.onChange(function(url){
    console.log(url);
  });

  $location.onLoaded(function(url){
    console.log(url);
  });

  //链接当前route到view/demo/user/info
  $location.href('view/demo/user/info');
});
&lt;/script&gt;
</code></pre>
<h4>onCloseBefore</h4>
<p>onCloseBefore(callback)</p>
<p>关闭前事件，返回false可终止关闭</p>
<p><strong>callback</strong>，事件执行callback(url)</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
   $location.onCloseBefore(function(){ return false;});
   $location.close()
});
&lt;/script&gt;
</code></pre>
<h4>onClosed</h4>
<p>onClosed(callback)</p>
<p>关闭后事件</p>
<p><strong>callback</strong>，事件执行callback(url)</p> 
<pre><code>&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.action('list', function($view, $location){
   $location.onClosed(function(){ return console.log('close');});
   $location.close()
});
&lt;/script&gt;
</code></pre>
<h4>bingo.location.onHref</h4>
<p>bingo.location.onHref(callback)</p>
<p>监测href事件, 控制href连接, 全局生效</p>
<p><strong>callback</strong>，事件执行function(jNode, url, target){}<br>如果callback返回false, 取消默认动作</p> 
<pre><code>&lt;a href="#view/demo/user/list" bg-target="main"&gt;列表&lt;/a&gt;

&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
//监测href
bingo.location.onHref(function(jNode, url, target){
    var $loc = bingo.location(jNode);
    $loc.href(href, target);
    return false;//如果返回false, 取消默认动作
});
&lt;/script&gt;
</code></pre>
<h4>bingo.location.onLoaded</h4>
<p>bingo.location.onLoaded(location)</p>
<p>监测所有location的onLoaded, 所有location加载后事件, 全局生效</p>
<p><strong>callback</strong>，事件执行function(location){}</p> 
<pre><code>&lt;a href="#view/demo/user/list" bg-target="main"&gt;列表&lt;/a&gt;

&lt;div bg-route="view/demo/user/list" bg-route-name="main"&gt;&lt;div&gt;
&lt;script&gt;
bingo.location.onLoaded(function(location){
  
});
&lt;/script&gt;
</code></pre>
			</div>

																						<h5 id="text_55687" class="sin_target">$cache</h5>
<div class="sin_text">
    					<h4>$cache</h4>
<p>$cache</p>
<p>缓存数据，默认最大记录数100</p> 
<pre><code>bingo.action('list', function($view, $cache){
  $cache.key('title').set('标题');

  var title = $cache.key('title').get();
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>key</h4>
<p>key(key)</p>
<p>获取或设置当前key</p>
<h4>get</h4>
<p>get()</p>
<p>根据当前key，获取缓存值</p>
<h4>set</h4>
<p>set()</p>
<p>根据当前key，设置缓存值</p>
<h4>has</h4>
<p>has()</p>
<p>根据当前key，是否有缓存</p>
<h4>clear</h4>
<p>clear()</p>
<p>根据当前key，删除缓存</p>
<h4>clearAll</h4>
<p>clearAll()</p>
<p>清除所有缓存</p>
<h4>max</h4>
<p>max(max)</p>
<p>获取或设置最大缓存数量，默认-1为无限</p> 
<pre><code>bingo.action('list', function($view, $cache){
  $cache.max(100);//最大缓存100个
  $cache.key('title'); //设置当前key为title
  $cache.set('标题'); //设置title为标题
  var title = $cache.get(); //获取title值
  $cache.clear('title');//删除title
  $cache.clearAll();
});
</code></pre>
			</div>

																						<h5 id="text_55688" class="sin_target">$param</h5>
<div class="sin_text">
    					<h4>$param</h4>
<p>$param(key[, value])</p>
<p>$param 主要处理参数传递问题，如两个action之间传送数据</p>
<p><strong>key</strong> 设置或获取$param的key</p>
<p><strong>value</strong> 要设置的值</p> 
<pre><code>var action1 = bingo.action(function($view, $param){
   //设置myTitle参数
   $param('myTitle', '我的标题');
});

var action2 = bingo.action(function($view, $param){
   //获取myTitle参数
   var title = $param('myTitle');
   title === '我的标题';
});
</code></pre>
<p><code>注意：$param使用后，会自动释放，所以只能使用一次</code></p> 
<pre><code>var action2 = bingo.action(function($view, $param){
   //获取myTitle参数
   var title = $param('myTitle');
   title === '我的标题';

   //第二次获取为undefined, $param('myTitle')已经释放
   title = $param('myTitle');
   title === undefined;
});
</code></pre>
			</div>

																						<h5 id="text_55689" class="sin_target">$timeout</h5>
<div class="sin_text">
    					<p><strong>$timeout</strong> 和setTimeout 的使用方法和场景都是一样，只不过$timeout封装自动同步数据：<br> </p>
<pre><code><br>setTimeout(function(){
   $view.title = '新标题';
   $view.$update();
}, 1000);

//$timeout不用$view.$update
$timeout(function(){
   $view.title = '新标题';
}, 1000);
</code></pre>
<p></p>
			</div>

																						<h5 id="text_55690" class="sin_target">$render</h5>
<div class="sin_text">
    					<h4>$render</h4>
<p>$render(tmpl)</p>
<p>$render是一个文本模板解释引擎，如jsRender之类的，在框架它已经完美结合在html绑定模板里去了，具体详情可能参考指令**bg-render**。为什么有了html绑定模板，还要render模板呢？原因html绑定模板一般是先解释成dom node，然后遍历所有dom node进行编译，然而这过程会产生大量不需要的dom node，这样会影响编译性能；如果我们先render本文本生成比较干净的html绑定模板，这样就能节省很多计算资源；</p>
<p><strong>tmpl</strong>：render 模板</p> 
<pre><code>bingo.action('list', function($view, $render){
  //render模板
  var tmpl = '&lt;div&gt;{{: item.name}}&lt;/div&gt;';
  //数据
  var list =[{name:'小明'}, {name:'小李'}];
  //创建render, 并解释输出到html
  var rd = $render(tmpl);
  var html = rd.render(list);
  //解释结果
  html === '&lt;div&gt;小明&lt;/div&gt;&lt;div&gt;小明&lt;/div&gt;'

});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>render</h4>
<p>render(data[, itemName][, parentData][, parentWithIndex][, outWithDataList][,formatter])</p>
<p>根据数据解释render模板</p>
<p><strong>data</strong>：数据源，可以为空、数组及其它所有数据类型<br><strong>itemName</strong>：可选, 模板里数据项名称，默认为’item’<br><strong>parentData</strong>：可选, 上级数据<br><strong>parentWithIndex</strong>：可选, 上级withindex, 如果没有应该为 -1<br><strong>outWithDataList</strong>：可选, 数组， 收集withDataList, 具体用法请参考bg-render源码<br><strong>formatter</strong>：可选, function (s, role) { return s;}<br> </p>
<pre><code><br>bingo.action('list', function($view, $render){
  //render模板
  var tmpl = '&lt;div&gt;{{myItem.name}}&lt;/div&gt;';
  //数据
  var list =[{name:'小明'}, {name:'小李'}];
  //创建render, 并解释输出到html
  var rd = $render(tmpl);
  var html = rd.render(list, 'myItem');//设置数据项名称为'myItem'
  //解释结果
  html === '&lt;div&gt;小明&lt;/div&gt;&lt;div&gt;小明&lt;/div&gt;'

});
</code></pre>
<p></p>
<p><code>详细render语句，可以参考 “模板render” 章节</code></p>
			</div>

																						<h5 id="text_55691" class="sin_target">$linq</h5>
<div class="sin_text">
    					<h4>$linq</h4>
<p>$linq(list)</p>
<p>主要负责前端数组的查询，排序，分组，分页，组装等;</p>
<p><strong>list</strong>：数组或arguments</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([1,2,3,4]).where(function(item){ return item &gt; 2}).toArray();
  list === [3,4]
});
</code></pre>
<h3>属性与方法：</h3> 
<hr>
<h4>where</h4>
<p>where(fn[, index][, count][, rever])</p>
<p>查询或过滤数据条件</p>
<p><strong>fn</strong>：处理方法function(item, index){}<br><strong>index</strong>：开始位置, 如果负数从后面算起<br><strong>count</strong>：查询到数据的数量<br><strong>rever</strong>：反向查询</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([1,2,3,4]).where(function(item,index){ return item &gt; 2; }, 1, 1, false).toArray();
  list === [3]
});
</code></pre>
<h4>select</h4>
<p>select(fn[, isMerge])</p>
<p>数据改造，组装</p>
<p><strong>fn</strong>：function(item, index){}<br><strong>isMerge</strong>：开始位置, 如果负数从后面算起 </p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([1,2,3,4]).select(function(item,index){ return { n: item}; }).toArray();
  list === [{n:3}, {n:4}]
});
</code></pre>
<h4>sort</h4>
<p>sort(fn)</p>
<p>数据排序</p>
<p><strong>fn</strong>：function(item1, item2){}<br>- item1 - item2:从小到大排序 - item2 - item1:从大到小排序<br>- item1 &gt; item2:从小到大排序<br>- item1 &lt; item2:从大到小排序</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([1,2,3,4]).sort(function(item1, item2){ return item2 - item1; }).toArray();
  list === [4,3,2,1]
});
</code></pre>
<h4>sortAsc/sortDesc</h4>
<p>sortAsc([p])</p>
<p>对数据升序或降序进行排序</p>
<p><strong>p</strong>：可选， 可以是空、属性名称或function(item){}</p> 
<pre><code>bingo.action('list', function($view, $linq){
  //通过数据项排序
  var list = $linq([1,2,3,4]).sortDesc().toArray();
  list === [4,3,2,1]

  //通过数据项属性'n'排序
  var list = $linq([{n:1},{n:2}]).sortDesc('n').toArray();
  list === [{n:2},{n:1}]

  //通过自定义内容排序
  var list = $linq([{n:1},{n:2}]).sortDesc(fucntion(item){return item.n; }).toArray();
  list === [{n:2},{n:1}]
});
</code></pre>
<h4>unique</h4>
<p>unique([p])</p>
<p>去除重复数据</p>
<p><strong>p</strong>：可选， 可以是空、属性名称或function(item){}</p> 
<pre><code>bingo.action('list', function($view, $linq){
  //通过数据项检查重复
  var list = $linq([1,1,2,2]).unique().toArray();
  list === [1,2]

  //通过数据项属性'n'检查重复
  var list = $linq([{n:1},{n:1},{n:2}]).unique('n').toArray();
  list === [{n:1},{n:2}]

  //通过自定义内容检查重复
  var list = $linq([{n:1},{n:1},{n:2}]).unique(fucntion(item){return item.n; }).toArray();
  list === [{n:1},{n:2}]
});
</code></pre>
<h4>group</h4>
<p>group(p[, groupName][, itemName])</p>
<p>数据分组</p>
<p><strong>p</strong>：可以是属性名称或function(item, index){}<br><strong>groupName</strong>：可选, 分组值名称, 默认group<br><strong>itemName</strong>：可选, 分组内容值名称, 默认items </p> 
<pre><code>bingo.action('list', function($view, $linq){
  //通过数据项属性'n'分组
  var list = $linq([{n:1},{n:1},{n:2}]).group('n').toArray();
  list === [{group:1, items:[{n:1},{n:1}]}, {group:2, items:[{n:2}]}]

  //设置groupName和itemName
  var list = $linq([{n:1},{n:1},{n:2}]).group('n', 'gval', 'children').toArray();
  list === [{gval:1, children:[{n:1},{n:1}]}, {gval:2, children:[{n:2}]}]

  //通过自定义内容进行分组
  var list = $linq([{n:1},{n:1},{n:2}]).group(function(item){return item;}).toArray();
  list === [{group:1, items:[{n:1},{n:1}]}, {group:2, items:[{n:2}]}]
});

</code></pre>
<h4>toArray</h4>
<p>toArray()</p>
<p>返回数据结果</p>
<h4>take</h4>
<p>take(pos[, count])</p>
<p>返回指定义位置和数理的数据结果</p>
<p><strong>pos</strong>：开始位置</p>
<p><strong>count</strong>：可选，获取数量，默认全部</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([1,2,3,4]).where(function(item){ return item &gt; 2}).take(0,1);
  list === [3]
});
</code></pre>
<h4>first/last</h4>
<p>first([defaultValue])</p>
<p>返回第一个/最后一个数据结果</p>
<p><strong>defaultValue</strong>：可选，如果没有查找到数据，使用这个值代表</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var data = $linq([1,2,3,4]).where(function(item){ return item &gt; 2}).first();
  data === 3
});
</code></pre>
<h4>toPage</h4>
<p>toPage(page, pageSize)</p>
<p>按分页返回数据结果</p>
<p><strong>page</strong>：当前页面数（第几页），从1开始计数<br><strong>pageSize</strong>：每页数据数量</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var data = $linq([1,2,3,4,5,6,7]).where(function(item){ return item &gt; 2}).toPage(1,2);
  data === {
                    currentPage: 1, totalPage: 3, pageSize: 2,
                    totals: 5, list: [3,4]
                }
});
</code></pre>
<h4>each</h4>
<p>each(fn[, index][, rever])</p>
<p>遍历数据项</p>
<p><strong>fn</strong>：遍历处理函数，function(item, index)<br><strong>index</strong>：开始位置, 如果负数从后面算起<br><strong>rever</strong>：反向遍历数据</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var list = $linq([{n:1},{n:5}]).where(function(item){ return item.n &gt; 2}).each(function(){ this.n++; }).toArray();
  list === [{n:6}]
});
</code></pre>
<h4>count</h4>
<p>count()</p>
<p>查询结果数量</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var n = $linq([{n:1},{n:5}]).where(function(item){ return item.n &gt; 2}).count();
  n === 1
});
</code></pre>
<h4>index</h4>
<p>index()</p>
<p>查询索引</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var n = $linq([{n:1},{n:5}]).where(function(item){ return item.n &gt; 2}).index();
  n === 1
});
</code></pre>
<h4>contain</h4>
<p>contain()</p>
<p>是否存在数据</p> 
<pre><code>bingo.action('list', function($view, $linq){
  var n = $linq([{n:1},{n:5}]).where(function(item){ return item.n &gt; 2}).contain();
  n === true
});
</code></pre>
<h4>sum/avg</h4>
<p>sum(p)</p>
<p>数据累加和平均值</p> 
<pre><code>bingo.action('list', function($view, $linq){
  //通过数据项累加数据
  var n = $linq([1,2]).sum();
  n=== 3

  //通过数据项属性'n'累加数据
  var n= $linq([{n:1},{n:2}]).sum('n');
  n=== 3

  //通过自定义内容累加数据
  var n = $linq([{n:1},{n:1},{n:2}]).sum(fucntion(item){return item.n; });
  n === 3
});
</code></pre>
			</div>

																												<h4 id="text_55700" class="sin_target">factory注入</h4>
<div class="sin_text">
    					<p>上面定义了factory <strong>$var</strong>, 那我们可以通过下面代码行进注入<br> </p>
<pre><code><br>var $varInject  = bingo.factory('$var').view($view).inject();

var var1 = $varInject(1111);
var1.$subs(function(){}, ....
</code></pre>
<br>上面的**$varInject**就是返回factory定义的**$var**实体了, 这时它就可以当**$var**使用了；
<p></p>
<p>再来看下面代码，定义**action1**:<br> </p>
<pre><code><br>var action1 = bingo.action(function($view, $var){
  var var1 = $var(111);
});
</code></pre>
<br>其实它大概原理如下面代码：
<br> 
<pre><code><br>//定义要注入的方法
var actionDefFn = function($view, $var){
  var var1 = $var(111);
};

//开始注入
var action1 = bingo.factory(actionDefFn).view($view).inject();
</code></pre>
<br>其实上面两个代码原理是一样的。把**actionDefFn**当成一个临时**factory**， 编译器收集到**view**后，开始注入成**action**
<p></p>
			</div>

																																				<h2 id="category_13137">API参考</h2>
																								<h3 id="text_55701" class="sin_target">多版本共存问题</h3>
<div class="sin_text">
    					<p>考虑多个bingoJS版本共存，每版本会提供如：bingoV1或bingoV1_1, 写代码可以尽量考虑这样写：<br> </p>
<pre><code><br>(function (bingo) {
    "use strict";

    var ver = bingo.version + '';

})(bingoV1);//使用bingoV1, 表示主bingo 1版本

(function (bingo) {
    "use strict";

    var ver = bingo.version + '';

})(bingoV1_1);//使用bingoV1, 表示主bingo 1.1版本
</code></pre>
<p></p>
			</div>

																<h3 id="category_13126">基础方法/属性</h3>
																						<h4 id="text_55611" class="sin_target">version</h4>
<div class="sin_text">
    					<p>版本号, 内容如下:<br> </p>
<pre><code><br>//分别为主版本号.子版本号.修正版本号
{ major: 1, minor: 1, rev: 0}
</code></pre>
<br>
<strong>主版本</strong>：升级，是不考虑向下兼容问题
<p></p>
<p><strong>子版本号</strong>：升级，必须向下兼容,如果累积添加一定新要素,升级一个子版本</p>
<p><strong>修正版本号</strong>：升级，添加小量新功能,BUG修复</p>
			</div>

																						<h4 id="text_55612" class="sin_target">isDebug</h4>
<div class="sin_text">
    					<p>是否debug模式， 默认为false</p>
<p>如果打开开关，框架所有错误都可以在console打印出来，并且中止所有脚本断续执行，这点要注意。</p>
			</div>

																						<h4 id="text_55613" class="sin_target">prdtVersion</h4>
<div class="sin_text">
    					<p>你的项目版本号， 用于动态加载时使用的版本号， 目的是解决浏览器缓存问题</p>
			</div>

																						<h4 id="text_55614" class="sin_target">stringEmpty</h4>
<div class="sin_text">
    					<p>空字串</p>
			</div>

																						<h4 id="text_55615" class="sin_target">noop</h4>
<div class="sin_text">
    					<p>空方法</p>
			</div>

																						<h4 id="text_55616" class="sin_target">newLine</h4>
<div class="sin_text">
    					<p>换行符</p>
			</div>

																						<h4 id="text_55617" class="sin_target">trace</h4>
<div class="sin_text">
    					<p>向console报告出错信息，用于catch：<br> </p>
<pre><code><br>try{
....
} catch(e) {
  bingo.trace(e);
}
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55618" class="sin_target">isUndefined</h4>
<div class="sin_text">
    					<p>是否未定义值：<br> </p>
<pre><code><br>var name, id = 0;
bingo.isUndefined(name) === true;
bingo.isUndefined(id) === false;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55619" class="sin_target">isNull</h4>
<div class="sin_text">
    					<p>是否为空值：<br> </p>
<pre><code><br>var name, id = 0, age = null;
bingo.isNull(name) === true;
bingo.isNull(id) === false;
bingo.isNull(age ) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55620" class="sin_target">isBoolean</h4>
<div class="sin_text">
    					<p>是否Boolean类型：<br> </p>
<pre><code><br>var name, m = true;
bingo.isBoolean(name) === false;
bingo.isBoolean(m) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55621" class="sin_target">isNullEmpty</h4>
<div class="sin_text">
    					<p>是否空串：<br> </p>
<pre><code><br>var name, m = '', str = 'a';
bingo.isNullEmpty(name) === true;
bingo.isNullEmpty(m) === true;
bingo.isNullEmpty(str ) === false;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55622" class="sin_target">isFunction</h4>
<div class="sin_text">
    					<p>是否方法：<br> </p>
<pre><code><br>var name, fn = bingo.noop;
bingo.isFunction(name) === false;
bingo.isFunction(fn) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55623" class="sin_target">isNumeric</h4>
<div class="sin_text">
    					<p>是否数字：<br> </p>
<pre><code><br>var name, n = 0, n1 = '1';
bingo.isNumeric(name) === false;
bingo.isNumeric(n) === true;
bingo.isNumeric(n1) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55624" class="sin_target">isString</h4>
<div class="sin_text">
    					<p>是否字串：<br> </p>
<pre><code><br>var name, n = 0, n1 = '1';
bingo.isString(name) === false;
bingo.isString(n) === false;
bingo.isString(n1) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55625" class="sin_target">isObject</h4>
<div class="sin_text">
    					<p>是否object， 这里window, dom node为false：<br> </p>
<pre><code><br>var name, n = 0, o = {};
bingo.isObject(name) === false;
bingo.isObject(n) === false;
bingo.isObject(window) === false;
bingo.isObject(document.body) === false;
bingo.isObject(o) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55626" class="sin_target">isPlainObject</h4>
<div class="sin_text">
    					<p>是否json object：<br> </p>
<pre><code><br>var name, n = 0, o = {}, o1 = new bingo.noop();
bingo.isPlainObject(name) === false;
bingo.isPlainObject(n) === false;
bingo.isPlainObject(o1) === false;
bingo.isPlainObject(o) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55627" class="sin_target">isArray</h4>
<div class="sin_text">
    					<p>是否数组：<br> </p>
<pre><code><br>var name, n = 0, list = [];
bingo.isArray(name) === false;
bingo.isArray(n) === false;
bingo.isArray(list) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55628" class="sin_target">isWindow</h4>
<div class="sin_text">
    					<p>是否window对象：<br> </p>
<pre><code><br>bingo.isWindow(window) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55629" class="sin_target">isElement</h4>
<div class="sin_text">
    					<p>是否dom node对象：<br> </p>
<pre><code><br>bingo.isElement(document.body) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55630" class="sin_target">isStringEquals</h4>
<div class="sin_text">
    					<p>两个字串是否相等， 不分大小写：<br> </p>
<pre><code><br>bingo.isStringEquals('aa', 'aA') === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55631" class="sin_target">trim</h4>
<div class="sin_text">
    					<p>去除字串前后空白：<br> </p>
<pre><code><br>bingo.trim(' a a ') === 'a a';
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55632" class="sin_target">replaceAll</h4>
<div class="sin_text">
    					<p>字串替换, 替换所有匹配内容：<br> </p>
<pre><code><br>bingo.replaceAll('11accdE11F', '11', '') === 'accdEF';
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55633" class="sin_target">toStr</h4>
<div class="sin_text">
    					<p>强制转换成字串：<br> </p>
<pre><code><br>bingo.toStr(null) === '';
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55634" class="sin_target">inArray</h4>
<div class="sin_text">
    					<p>inArray(element, list[, index][, rever])</p>
<p>查询元素在数组里的索引， 如果返回-1, 没有搜索到</p>
<p><strong>element</strong>：要查询元素<br><strong>list</strong>：数组<br><strong>index</strong>：开始位置，如果为负数为后面开始计算，默认0<br><strong>rever</strong>：反向查询，默认false</p> 
<pre><code>bingo.inArray(1, [0,0,1]) == 2;
bingo.inArray(1, [0,0,1], 1) == 2;
bingo.inArray(1, [0,0,3]) == -1;
</code></pre>
			</div>

																						<h4 id="text_55635" class="sin_target">removeArrayItem</h4>
<div class="sin_text">
    					<p>removeArrayItem(element, list)</p>
<p>删除数组里元素，如果多个相同也会被删除</p>
<p><strong>element</strong>：要删除元素<br><strong>list</strong>：数组</p> 
<pre><code>bingo.removeArrayItem(1, [0,1,0,1]) == [0,0];
</code></pre>
			</div>

																						<h4 id="text_55636" class="sin_target">sliceArray</h4>
<div class="sin_text">
    					<p>sliceArray(list[, pos][, count])</p>
<p>提取数组, 支持arguments</p>
<p><strong>list</strong>：要删除元素<br><strong>pos</strong>：开始位置, 如果负数从后面算起，默认0<br><strong>count</strong>：提取数量，默认所有</p> 
<pre><code>bingo.sliceArray([0,1,2,3,4], 1) == [1,2,3,4];
bingo.sliceArray([0,1,2,3,4], -1) == [4];
bingo.sliceArray([0,1,2,3,4], 1, 2) == [1,2];
</code></pre>
			</div>

																						<h4 id="text_55637" class="sin_target">makeAutoId</h4>
<div class="sin_text">
    					<p>生成一个唯一数， 只对当前客户环境有用<br> </p>
<pre><code><br>bingo.makeAutoId()
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55638" class="sin_target">each</h4>
<div class="sin_text">
    					<p>each(list, callback[, index][, rever])</p>
<p>遍历数组</p>
<p><strong>list</strong>：数组<br><strong>callback</strong>：遍历callback, function(item, index)<br><strong>index</strong>：开始位置，如果为负数为后面开始计算，默认0<br><strong>rever</strong>：反向查询，默认false</p> 
<pre><code>bingo.each([0,0,1], function(item, index){
  this == item
});
</code></pre>
			</div>

																						<h4 id="text_55639" class="sin_target">eachProp</h4>
<div class="sin_text">
    					<p>eachProp(obj, callback)</p>
<p>遍历object owner属性</p>
<p><strong>obj</strong>：object<br><strong>callback</strong>：遍历callback, function(item, name)</p> 
<pre><code>bingo.eachProp({name:'le', age:23}, function(item, name){
  this == item
});
</code></pre>
			</div>

																						<h4 id="text_55640" class="sin_target">htmlEncode</h4>
<div class="sin_text">
    					<p>html编码</p> 
<pre><code>bingo.htmlEncode('&lt;br /&gt;') === '&lt;br /&gt;'
</code></pre>
			</div>

																						<h4 id="text_55641" class="sin_target">htmlDecode</h4>
<div class="sin_text">
    					<p>html解编码</p> 
<pre><code>bingo.htmlDecode('&lt;br /&gt;') === '&lt;br /&gt;'
</code></pre>
			</div>

																						<h4 id="text_55642" class="sin_target">urlEncode</h4>
<div class="sin_text">
    					<p>url编码</p> 
<pre><code>bingo.urlEncode('你好')=== '%E4%BD%A0%E5%A5%BD'
</code></pre>
			</div>

																						<h4 id="text_55643" class="sin_target">urlDecode</h4>
<div class="sin_text">
    					<p>url解编码</p> 
<pre><code>bingo.urlDecode('%E4%BD%A0%E5%A5%BD')=== '你好'
</code></pre>
			</div>

																						<h4 id="text_55644" class="sin_target">clearObject</h4>
<div class="sin_text">
    					<p>将object所有属性设置为null</p> 
<pre><code>bingo.clearObject({name:'le', age:23})=== {name:null, age:null}
</code></pre>
			</div>

																						<h4 id="text_55645" class="sin_target">extend</h4>
<div class="sin_text">
    					<p>扩展属性或方法</p> 
<pre><code>//扩展到bingo
bingo.extend({newName:'aaa'});
bingo.newName === 'aaa';

//扩展到第一个参数
var obj = bingo.extend({}, {name1:'111'}, {name2:'2222'});
obj.name1 === '111';
obj.name2 === '2222';
</code></pre>
			</div>

																						<h4 id="text_55646" class="sin_target">clone</h4>
<div class="sin_text">
    					<p>clone(obj[, deep])</p>
<p>复制json object</p>
<p><strong>obj</strong>：json object<br><strong>deep</strong>：是否深复制， 默认true</p> 
<pre><code>var o = {a: 1, b:{aaa:"111'}};
var o1 = bingo.clone(o);
</code></pre>
			</div>

																						<h4 id="text_55647" class="sin_target">proxy</h4>
<div class="sin_text">
    					<p>proxy(owner, fn)</p>
<p>代理owner</p>
<p><strong>owner</strong>：owner<br><strong>fn</strong>：代理内容</p> 
<pre><code>bingo.proxy({a:1}, function(){ this.a === 1;});
</code></pre>
			</div>

																						<h4 id="text_55648" class="sin_target">equals</h4>
<div class="sin_text">
    					<p>equals(p1, p2)</p>
<p>比较两个参数是否相等</p> 
<pre><code>bingo.equals({a:1}, {a:1}) === true;
</code></pre>
			</div>

																						<h4 id="text_55649" class="sin_target">datavalue</h4>
<div class="sin_text">
    					<p>datavalue(data, name[, value])</p>
<p>设置或获取data属性值</p>
<p><strong>data</strong>：owner<br><strong>name</strong>：属性名称，支持数组<br><strong>value</strong>：设置值</p> 
<pre><code>window.aaa = {bbb:1}
bingo.datavalue(window, 'aaa.bbb') === 1;
bingo.datavalue(window, 'aaa.ccc.d', 22);
JSON.stringify(window.aaa) === "{"bbb":1,"ccc":{"d":22}}"

//技术数组
bingo.datavalue(window, 'aaa.ccc.list[2]', 33)
JSON.stringify(window.aaa) === "{"bbb":1,"ccc":{"d":22,"list":[null,null,33]}}"
</code></pre>
			</div>

																						<h4 id="text_55650" class="sin_target">Event</h4>
<div class="sin_text">
    					<p>Event([owner])</p>
<p>定义一个事件</p>
<p><strong>owner</strong>：设置事件的owner</p> 
<pre><code>//定义事件
var e = bingo.Event();
//绑定
e.on(function(arg1, arg2){
  console.log(arg1, arg2);
});
//触发
e.trigger([111, 222]);

</code></pre>
<h3>属性与方法：</h3>
<p>—</p>
<h4>on</h4>
<p>on(eventName, callback)</p>
<p>绑定一个事件，具体使用方法;<br> </p>
<pre><code><br>//绑定一个load事件, 并接收a,b数据
e.on('load', function(a, b){
  console.log('onload', a, b);
});
</code></pre>
<p></p>
<h4>one</h4>
<p>one(eventName, callback)</p>
<p>绑定一个事件, 与on一样，但不同是这个绑定的事件，只会触发一次;</p>
<h4>trigger</h4>
<p>trigger(eventName, [args])</p>
<p>触发事件，可以传送参数，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
e.trigger('load', ['aaa', 'bbbb']);
</code></pre>
<br>
<code>注意这方法返回最后一个事件的值</code>
<p></p>
<h4>triggerHandler</h4>
<p>triggerHandler(eventName, [args])</p>
<p>触发第一个事件，可以传送参数，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
e.triggerHandler('load', ['aaa', 'bbbb']);
</code></pre>
<br>
<code>注意这方法返回事件的值</code>
<p></p>
<h4>end</h4>
<p>end(eventName, [args])</p>
<p>结束事件, 先触发事件并解除所有绑定事件, 以后绑定事件马上自动确发, 用于ready之类的场景<br> </p>
<pre><code><br>//结束load事件， 并传入a,b数据
e.end('load', ['aaa', 'bbbb']);
//如果再绑定事件会自动触发
e.on('load', function(a,b){});
</code></pre>
<p></p>
<h4>off</h4>
<p>off(eventName, [callback])</p>
<p>取消绑定事件，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
var fn = function(){};
e.on('load', fn);
//取消load事件里fn绑定
e.off('load', fn);
//取消load事件所有绑定
e.off('load')
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55651" class="sin_target">isEvent</h4>
<div class="sin_text">
    					<p>是否事件对象：<br> </p>
<pre><code><br>bingo.isEvent(bingo.Event()) === true;
</code></pre>
<p></p>
			</div>

																						<h4 id="text_55652" class="sin_target">using</h4>
<div class="sin_text">
    					<p>using(routePath[, callback][, priority])</p>
<p>动态加载js</p>
<p><strong>routePath</strong>：route url<br><strong>callback</strong>：加载完成后，要处理内容<br><strong>priority</strong>：优先级，越小越高，默认50</p> 
<pre><code>bingo.using('service/userService');
bingo.using('service/userService', function(){}, 50)
</code></pre>
			</div>

																						<h4 id="text_55653" class="sin_target">usingMap</h4>
<div class="sin_text">
    					<p>usingMap(mapPath, paths)</p>
<p>合并js时用, 定义using路径影射</p>
<p><strong>mapPath</strong>：映射到的路径<br><strong>paths</strong>：一组原路径,[“a.js”, “b.js”…]</p> 
<pre><code>//使用map, 合并js时用, 以下是将, equals.js和JSON.js, 影射到equals1.js
bingo.usingMap("scripts/equals1.js", ["scripts/equals.js", "scripts/JSON.js"]);

scr*.js影射到all.js, *号代表多个字符
bingo.usingMap("scripts/all.js", ["scripts/scr*.js"]);

scr?.js影射到all.js， ?号代表单个字符
bingo.usingMap("scripts/all.js", ["scripts/scr?.js"]);


scripts目录下所有文件影射到all.js， **号代表所有
bingo.usingMap("scripts/all.js", ["scripts/**"]);
</code></pre>
			</div>

																						<h4 id="text_55654" class="sin_target">ready</h4>
<div class="sin_text">
    					<p>ready方法，代表bingo已经准备好了。<br> </p>
<pre><code><br>bingo.ready(function(){
  //准备好，得相关逻辑
});
</code></pre>
<p></p>
			</div>

																						<h3 id="category_13129">类</h3>
																<h4 id="category_13122">类库</h4>
																						<h5 id="text_55581" class="sin_target">bingo.Class.Base</h5>
<div class="sin_text">
    					<p><strong>bingo.Class.Base</strong>是bingo.Class定义类的基础类，它目前集成了对事件和销毁支持，这里我们先定义一个类:<br> </p>
<pre><code><br>var aCls = bingo.Class(function(){

});
</code></pre>
<p></p>
<h4>on</h4>
<p>on(eventName, callback)</p>
<p>绑定一个事件，具体使用方法;<br> </p>
<pre><code><br>var a = aCls.NewObject();
//绑定一个load事件, 并接收a,b数据
a.on('load', function(a, b){
  console.log('onload', a, b);
});
</code></pre>
<p></p>
<h4>one</h4>
<p>one(eventName, callback)</p>
<p>绑定一个事件, 与on一样，但不同是这个绑定的事件，只会触发一次;</p>
<h4>trigger</h4>
<p>trigger(eventName, [args])</p>
<p>触发事件，可以传送参数，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
a.trigger('load', ['aaa', 'bbbb']);
</code></pre>
<br>
<code>注意这方法返回最后一个事件的值</code>
<p></p>
<h4>triggerHandler</h4>
<p>triggerHandler(eventName, [args])</p>
<p>触发第一个事件，可以传送参数，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
a.triggerHandler('load', ['aaa', 'bbbb']);
</code></pre>
<br>
<code>注意这方法返回事件的值</code>
<p></p>
<h4>end</h4>
<p>end(eventName, [args])</p>
<p>结束事件, 先触发事件并解除所有绑定事件, 以后绑定事件马上自动确发, 用于ready之类的场景<br> </p>
<pre><code><br>//结束load事件， 并传入a,b数据
a.end('load', ['aaa', 'bbbb']);
//如果再绑定事件会自动触发
a.on('load', function(a,b){});
</code></pre>
<p></p>
<h4>off</h4>
<p>off(eventName, [callback])</p>
<p>取消绑定事件，具体使用方法;<br> </p>
<pre><code><br>//发送load事件， 并传入a,b数据
var fn = function(){};
a.on('load', fn);
//取消load事件里fn绑定
a.off('load', fn);
//取消load事件所有绑定
a.off('load')
</code></pre>
<p></p>
<h4>dispose</h4>
<p>dispose()</p>
<p>销毁对象，其实是对对象属性和方法设置null，为什么要用它了，当在复杂的使用环境中，很多情况我们都不知道谁引用了谁，特别引用dom node，很容易内存产生压力，这时我们可以简单调用dispose来断开引用，本框架提供bingo.linkToDom.LinkToDomClass与dom node连接起来，实现自动销毁（即dom node给删除了，对象也自动销毁）；</p>
<h4>onDispose</h4>
<p>onDispose(callback)</p>
<p>销毁事件，当调用dispose时，就发关onDispose事件<br> </p>
<pre><code><br>//绑定销毁事件
a.onDispose(function(){
  console.log('dispose');
});
//销毁对象
a.dispose();
</code></pre>
<p></p>
<h4>isDisposed</h4>
<p>对象是否已经被销毁<br> </p>
<pre><code><br>//销毁对象
a.dispose();
a.isDisposed === true;
</code></pre>
<p></p>
<h4>disposeByOther</h4>
<p>disposeByOther(obj)</p>
<p>当obj对象释放时自动释放这个对象，当然obj也是bingo.Class定义出的对象<br> </p>
<pre><code><br>var b = aCls.NewObject();
b.disposeByOther(a)
//销毁对象
a.dispose();
a.isDisposed === true;
b.isDisposed === true;
</code></pre>
<p></p>
<h4>$prop</h4>
<p>设置或获取Prop所有属性</p> 
<pre><code>var o = bingo.Class.Base.NewObject();
var prop = o.$prop();
var o111 = bingo.Class.Base.NewObject();
o111.$prop(prop);
</code></pre>
			</div>

																												<h4 id="text_55661" class="sin_target">类的定义 bingo.Class</h4>
<div class="sin_text">
    					<p>bingo.Class是类定义的方法，本框架对定义类只是简单对继承，数据分离（不见意分离），类的初始化作了规范，没有做的太复杂的程度，使用时还是有一些要注意的，请看下面定义：<br> </p>
<pre><code><br>var aCls = bingo.Class(function () {

    //定义静态方法
    this.Static({
        stFn: function () {
        }
    });

    //定义属性Prop
    this.Prop({
        vv:1
    });

    //定义类普通属性和方法
    this.Define({
        _a: 1,
        fn: function () {
            this._a = 1;
        }
    });

    //初始化
    this.Initialization(function (p) {
        this._a = 22 + p;

        //如果是object, 数组都要分离， 最好在初始化里定义， 不要放在Define里
        //当然框架会做分离，但对性能有影响
        this.datas = { a: 1, b: 1 }

    });

});

//新建实例， 就初始方法为1
var a = aCls.NewObject(1);
//使用a.fn方法
a.fn();
//使用data.a
a.datas.a = 111;
//使用vv prop
a.vv(1111);
//原型链
a instanceof Object
b instanceof bingo.Class.Base
a instanceof aCls
//使用静态方法stFn
aCls.stFn();
</code></pre>
<p></p>
<p>下面看看如果定义子类：<br> </p>
<pre><code><br>//定义bCls 继续 aCls
var bCls = bingo.Class(aCls, function () {
    //设置_base为aCls定义
    var _base = aCls.prototype;
    

    this.Define({
        //重写父类fn方法
        fn: function () {

            //调用aCls方法
            _base.fn.apply(arguments);
        },
        fnB: function () {
        }
    });

    this.Initialization(function (p) {
        //初始aCls
        this.base(p);

        this._bb = 22 + p;
    });

});
//新建实例， 就初始方法为1
var b = bCls.NewObject(1);
//使用a.fn方法
b.fn();
//使用data.a
b.datas.a = 111;
//使用vv prop
b.vv(1111);
//原型链
b instanceof Object
b instanceof bingo.Class.Base
b instanceof aCls
b instanceof bCls
</code></pre>
<br>上面代码说明了定义类和子类的过程；定义类的注意的问题，如何继承，如果重写父方法等，都是JS定义类常用到的场景；
<p></p>
<p><code>特别要注意的是bingo.Class定义出来的类都是继承bingo.Class.Base类，它支持定义了事件和销毁方法，具体信息可以查看bingo.Class.Base</code></p>
<h4>Prop</h4>
<p>Prop({})</p>
<p>定义类属性，属性是支持链接写法的：<br> </p>
<pre><code><br>//设置值
a.vv(1111);
//获取值
var v = a.vv()
//链写
var v1 = a.vv(2222).vv();
</code></pre>
<br>支持get/set:
<br> 
<pre><code><br>Prop({
  nn:{
    set:function(value){ this.value = value;}
    get:function(){ return this.value;}
  }
})
</code></pre>
<p></p>
<h4>Define</h4>
<p>Define({})</p>
<p>定义普通js属性或方法，可以认为直接向prototype写入属性或方法,如果是object类型属性会到分离处理(不建议object类型放在这里，尽量放在初始方法里)<br> </p>
<pre><code><br>Define({
  name:'obj1',
  fn:function(){ return this.name}
});
</code></pre>
<p></p>
<h4>Initialization</h4>
<p>Initialization(function(){})</p>
<p>类的初始方法：<br> </p>
<pre><code><br>Initialization(function(p1, p2){
  //父类初始
  this.base();
  this.name = p1;
})
</code></pre>
<p></p>
<h4>Static</h4>
<p>Static({})</p>
<p>定义类的静态方法或属性：<br> </p>
<pre><code><br>Static({
  stFn:function(){}
})
</code></pre>
<p></p>
<h4>类的扩展</h4>
<p>extend({})</p>
<p>对类的后期扩展：<br> </p>
<pre><code><br>var aCls = bingo.Class(function(){});

//对aCls扩展方法aFn
aCls.extend({
  aFn:function(){}
});

var a = aCls.NewObject()
a.aFn();
</code></pre>
<p></p>
			</div>

																															
				  		<div class="sin_info" style="margin-top: 10px;">
	  			bingoJS团队所有
	  		</div>
	  				</div>
		<div class="clear"></div>
	</div>
	<div id="bottom_begin"></div>
	<div class="sin_footer">
		<div>
			Powered by <a href="http://www.oschina.net" target="_blank">开源中国</a>
		</div>
	</div>
	<script>
		//计算图片的真实大小，如果超过编辑区域，则进行限制
		var resizePicWidth = function(pic_width){
			var imgs = document.getElementsByTagName("img");
            var j=0;
			for(var i=0;i<imgs.length;i++){
                var realWidth;	//真实的宽度
                var realHeight;		//真实的高度
                //这里做下说明，$("<img/>")这里是创建一个临时的img标签，类似js创建一个new Image()对象！
				var newImg = new Image();
				newImg.onload=function() {
                    realWidth = imgs[j].width;
                    realHeight = imgs[j].height;
                    //如果真实的宽度大于规定的宽度就按照100%显示
                    if(realWidth>=pic_width){
						imgs[j].style.width=(pic_width) + "px";
                    } else{//如果小于浏览器的宽度按照原尺寸显示
						imgs[j].style.width=realWidth+'px';
                    }
                    j++;
                }
				newImg.src=imgs[j].src;
			}

		}
		var currentNode = null;
		window.onscroll=function(){
            var h = document.getElementById("top_end").getBoundingClientRect().top;
            if(h<=0){
				document.getElementById("sin_navi_id").className='sin_navi sin_navi_nomove';
				document.getElementById("sin_content_id").className='sin_content sin_content_mar';
            }else{
                document.getElementById("sin_navi_id").className='sin_navi';
                document.getElementById("sin_content_id").className='sin_content';
            }
            comLayout();
            var arr= new Array();
            var index = 0;
			var sinTargets = getClass("h2","sin_target");
			for(var i=0;i<sinTargets.length;i++){
                var th = sinTargets[i].getBoundingClientRect().top - 80;	                if(th<=0){
                    arr[index] = new Array();
                    arr[index][0] = sinTargets[i].getAttribute("id");
                    arr[index][1] = th;
                    index++;
                }
			}

            var curr = bubbleSort(arr);
            if(curr!=null && curr!=currentNode){
				var oldCurrIds = getClass("li","sin_navi_current");
                if(oldCurrIds && oldCurrIds[0]){
                    var oid=oldCurrIds[0].getAttribute("id");
                    document.getElementById(oid).className=" ";
                }
				document.getElementById("navi_"+curr).className="sin_navi_current";
                currentNode = curr;
            }
        }
		
		
	    window.onresize = function(){
            comLayout();
		}

        var ch = document.getElementById("sin_navi_id").offsetHeight;

	    function comLayout() {
	        var h = document.documentElement.clientHeight;
	    	if(ch<h){
	    		return;
	    	}
		    var i = document.getElementById("bottom_begin").getBoundingClientRect().top;
	        if(i<h){
                document.getElementById("sin_navi_id").style.height=(i+"px");
		   	}else{
                document.getElementById("sin_navi_id").style.height=(h+"px");
		   	}
	    }
	    
	    function bubbleSort(arr){
	    	var i= arr.length;
	    	if(i<=0){
	    		return null;
	    	}
	    	var j;
			var tempExchangVal;
			while(i>0){
				for(j=0;j<i-1;j++){
					if(arr[j][1] < arr[j+1][1]){
						tempExchangVal=arr[j];
						arr[j]=arr[j+1];
						arr[j+1]=tempExchangVal;
					}
				}
				i--;
			}
			return arr[0][0];
		}
	    comLayout();
	    resizePicWidth(680);

        function getClass(tagname, className) { //tagname指元素，className指class的值
            //判断浏览器是否支持getElementsByClassName，如果支持就直接的用
            if (document.getElementsByClassName) {
                return document.getElementsByClassName(className);
            }
            else {    //当浏览器不支持getElementsByClassName的时候用下面的方法
                var tagname = document.getElementsByTagName(tagname);  //获取指定元素
                var tagnameAll = [];     //这个数组用于存储所有符合条件的元素
                for (var i = 0; i < tagname.length; i++) {     //遍历获得的元素
                    if (tagname[i].className == className) {     //如果获得的元素中的class的值等于指定的类名，就赋值给tagnameAll
                        tagnameAll[tagnameAll.length] = tagname[i];
                    }
                }
                return tagnameAll;
            }
        }
	</script>
</body>
</html>	
<!-- Generated by OsChina.NET (init:1[ms],page:489[ms],ip:183.17.125.48) -->